1mod slice_mut_writer;
8pub use self::slice_mut_writer::SliceMutWriter;
9
10use core::fmt;
11
12use crate::alloc::Vec;
13use crate::{Allocator, Context};
14
15mod sealed {
16 use super::Writer;
17
18 pub trait Sealed {}
19 impl<W> Sealed for &mut W where W: ?Sized + Writer {}
20 #[cfg(feature = "std")]
21 impl<W> Sealed for crate::wrap::Wrap<W> where W: std::io::Write {}
22 impl Sealed for &mut [u8] {}
23}
24
25pub trait IntoWriter
27where
28 Self: self::sealed::Sealed,
29{
30 type Ok;
32
33 type Writer: Writer<Ok = Self::Ok>;
35
36 fn into_writer(self) -> Self::Writer;
38}
39
40pub trait Writer {
42 type Ok;
44
45 type Mut<'this>: Writer
56 where
57 Self: 'this;
58
59 fn finish<C>(&mut self, cx: C) -> Result<Self::Ok, C::Error>
61 where
62 C: Context;
63
64 fn borrow_mut(&mut self) -> Self::Mut<'_>;
66
67 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
69 where
70 C: Context;
71
72 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
74 where
75 C: Context;
76
77 #[inline]
79 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
80 where
81 C: Context,
82 {
83 self.write_bytes(cx, &[b])
84 }
85}
86
87impl<'a, W> IntoWriter for &'a mut W
88where
89 W: ?Sized + Writer,
90{
91 type Ok = W::Ok;
92 type Writer = &'a mut W;
93
94 #[inline]
95 fn into_writer(self) -> Self::Writer {
96 self
97 }
98}
99
100impl<W> Writer for &mut W
101where
102 W: ?Sized + Writer,
103{
104 type Ok = W::Ok;
105 type Mut<'this>
106 = &'this mut W
107 where
108 Self: 'this;
109
110 #[inline]
111 fn finish<C>(&mut self, cx: C) -> Result<Self::Ok, C::Error>
112 where
113 C: Context,
114 {
115 (*self).finish(cx)
116 }
117
118 #[inline]
119 fn borrow_mut(&mut self) -> Self::Mut<'_> {
120 self
121 }
122
123 #[inline]
124 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
125 where
126 C: Context,
127 {
128 (*self).extend(cx, buffer)
129 }
130
131 #[inline]
132 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
133 where
134 C: Context,
135 {
136 (*self).write_bytes(cx, bytes)
137 }
138
139 #[inline]
140 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
141 where
142 C: Context,
143 {
144 (*self).write_byte(cx, b)
145 }
146}
147
148#[cfg(feature = "alloc")]
149impl Writer for rust_alloc::vec::Vec<u8> {
150 type Ok = ();
151 type Mut<'this>
152 = &'this mut Self
153 where
154 Self: 'this;
155
156 #[inline]
157 fn finish<C>(&mut self, _: C) -> Result<Self::Ok, C::Error>
158 where
159 C: Context,
160 {
161 Ok(())
162 }
163
164 #[inline]
165 fn borrow_mut(&mut self) -> Self::Mut<'_> {
166 self
167 }
168
169 #[inline]
170 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
171 where
172 C: Context,
173 {
174 self.write_bytes(cx, buffer.as_slice())
176 }
177
178 #[inline]
179 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
180 where
181 C: Context,
182 {
183 self.extend_from_slice(bytes);
184 cx.advance(bytes.len());
185 Ok(())
186 }
187
188 #[inline]
189 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
190 where
191 C: Context,
192 {
193 self.push(b);
194 cx.advance(1);
195 Ok(())
196 }
197}
198
199impl<'a> IntoWriter for &'a mut [u8] {
200 type Ok = usize;
201 type Writer = SliceMutWriter<'a>;
202
203 #[inline]
204 fn into_writer(self) -> Self::Writer {
205 SliceMutWriter::new(self)
206 }
207}
208
209pub struct BufWriter<A>
211where
212 A: Allocator,
213{
214 buf: Vec<u8, A>,
215}
216
217impl<A> BufWriter<A>
218where
219 A: Allocator,
220{
221 pub fn new(alloc: A) -> Self {
223 Self {
224 buf: Vec::new_in(alloc),
225 }
226 }
227
228 pub fn into_inner(self) -> Vec<u8, A> {
230 self.buf
231 }
232}
233
234impl<A> Writer for BufWriter<A>
235where
236 A: Allocator,
237{
238 type Ok = ();
239 type Mut<'this>
240 = &'this mut Self
241 where
242 Self: 'this;
243
244 #[inline]
245 fn finish<C>(&mut self, _: C) -> Result<Self::Ok, C::Error>
246 where
247 C: Context,
248 {
249 Ok(())
250 }
251
252 #[inline]
253 fn borrow_mut(&mut self) -> Self::Mut<'_> {
254 self
255 }
256
257 #[inline]
258 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
259 where
260 C: Context,
261 {
262 self.buf
263 .extend_from_slice(buffer.as_slice())
264 .map_err(cx.map())?;
265 Ok(())
266 }
267
268 #[inline]
269 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
270 where
271 C: Context,
272 {
273 self.buf.extend_from_slice(bytes).map_err(cx.map())?;
274 Ok(())
275 }
276}
277
278#[derive(Debug)]
280struct SliceOverflow {
281 n: usize,
282 capacity: usize,
283}
284
285impl fmt::Display for SliceOverflow {
286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 let SliceOverflow { n, capacity } = self;
288
289 write!(
290 f,
291 "Tried to write {n} bytes to slice, with a remaining capacity of {capacity}"
292 )
293 }
294}