musli/writer.rs
1//! Trait governing how to write bytes.
2//!
3//! To adapt [`std::io::Write`] types, see the [`wrap`] function.
4//!
5//! [`wrap`]: crate::wrap::wrap
6
7mod 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
25/// Coerce a type into a [`Writer`].
26///
27/// # Examples
28///
29/// ```
30/// use musli::{Context, IntoWriter, Writer};
31/// use musli::context;
32///
33/// let mut buffer = Vec::new();
34/// let mut writer = (&mut buffer).into_writer();
35/// let cx = context::new();
36///
37/// writer.write_bytes(&cx, b"Hello")?;
38/// writer.finish(&cx)?;
39///
40/// assert_eq!(buffer, b"Hello");
41/// # Ok::<_, musli::context::ErrorMarker>(())
42/// ```
43pub trait IntoWriter
44where
45 Self: self::sealed::Sealed,
46{
47 /// The output of the writer which will be returned after writing.
48 type Ok;
49
50 /// The writer type.
51 type Writer: Writer<Ok = Self::Ok>;
52
53 /// Convert the type into a writer.
54 fn into_writer(self) -> Self::Writer;
55}
56
57/// The trait governing how a writer works.
58///
59/// # Examples
60///
61/// ```
62/// use musli::{Context, Writer};
63/// use musli::context;
64///
65/// // Example using Writer as a trait bound
66/// fn write_greeting<W, C>(mut writer: W, cx: C) -> Result<W::Ok, C::Error>
67/// where
68/// W: Writer,
69/// C: Context,
70/// {
71/// writer.write_bytes(cx, b"Hello")?;
72/// writer.write_byte(cx, b' ')?;
73/// writer.write_bytes(cx, b"World")?;
74/// writer.finish(cx)
75/// }
76///
77/// let mut writer = Vec::new();
78/// let cx = context::new();
79///
80/// write_greeting(&mut writer, &cx)?;
81/// assert_eq!(writer, b"Hello World");
82/// # Ok::<_, context::ErrorMarker>(())
83/// ```
84pub trait Writer {
85 /// The value returned from writing the value.
86 type Ok;
87
88 /// Reborrowed type.
89 ///
90 /// Why oh why would we want to do this over having a simple `&'this mut T`?
91 ///
92 /// We want to avoid recursive types, which will blow up the compiler. And
93 /// the above is a typical example of when that can go wrong. This ensures
94 /// that each call to `borrow_mut` dereferences the [`Reader`] at each step to
95 /// avoid constructing a large muted type, like `&mut &mut &mut VecWriter`.
96 ///
97 /// [`Reader`]: crate::reader::Reader
98 type Mut<'this>: Writer
99 where
100 Self: 'this;
101
102 /// Finalize the writer and return the output.
103 fn finish<C>(&mut self, cx: C) -> Result<Self::Ok, C::Error>
104 where
105 C: Context;
106
107 /// Reborrow the current type.
108 ///
109 /// # Examples
110 ///
111 /// ```
112 /// use musli::{Context, Writer};
113 /// use musli::context;
114 ///
115 /// let mut writer = Vec::new();
116 /// let cx = context::new();
117 ///
118 /// {
119 /// let mut borrowed = writer.borrow_mut();
120 /// borrowed.write_bytes(&cx, b"Hello")?;
121 /// }
122 ///
123 /// writer.write_bytes(&cx, b" World")?;
124 /// writer.finish(&cx)?;
125 /// assert_eq!(writer, b"Hello World");
126 /// # Ok::<_, musli::context::ErrorMarker>(())
127 /// ```
128 fn borrow_mut(&mut self) -> Self::Mut<'_>;
129
130 /// Write a buffer to the current writer.
131 ///
132 /// This method is used internally to write a musli Vec buffer to the writer.
133 /// Most users will use [`write_bytes`] instead.
134 ///
135 /// [`write_bytes`]: Writer::write_bytes
136 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
137 where
138 C: Context;
139
140 /// Write bytes to the current writer.
141 ///
142 /// # Examples
143 ///
144 /// ```
145 /// use musli::{Context, Writer};
146 /// use musli::context;
147 ///
148 /// let mut writer = Vec::new();
149 /// let cx = context::new();
150 ///
151 /// writer.write_bytes(&cx, b"Hello")?;
152 /// writer.write_bytes(&cx, b" ")?;
153 /// writer.write_bytes(&cx, b"World")?;
154 /// writer.finish(&cx)?;
155 /// assert_eq!(writer, b"Hello World");
156 /// # Ok::<_, musli::context::ErrorMarker>(())
157 /// ```
158 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
159 where
160 C: Context;
161
162 /// Write a single byte.
163 #[inline]
164 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
165 where
166 C: Context,
167 {
168 self.write_bytes(cx, &[b])
169 }
170}
171
172impl<'a, W> IntoWriter for &'a mut W
173where
174 W: ?Sized + Writer,
175{
176 type Ok = W::Ok;
177 type Writer = &'a mut W;
178
179 #[inline]
180 fn into_writer(self) -> Self::Writer {
181 self
182 }
183}
184
185impl<W> Writer for &mut W
186where
187 W: ?Sized + Writer,
188{
189 type Ok = W::Ok;
190 type Mut<'this>
191 = &'this mut W
192 where
193 Self: 'this;
194
195 #[inline]
196 fn finish<C>(&mut self, cx: C) -> Result<Self::Ok, C::Error>
197 where
198 C: Context,
199 {
200 (*self).finish(cx)
201 }
202
203 #[inline]
204 fn borrow_mut(&mut self) -> Self::Mut<'_> {
205 self
206 }
207
208 #[inline]
209 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
210 where
211 C: Context,
212 {
213 (*self).extend(cx, buffer)
214 }
215
216 #[inline]
217 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
218 where
219 C: Context,
220 {
221 (*self).write_bytes(cx, bytes)
222 }
223
224 #[inline]
225 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
226 where
227 C: Context,
228 {
229 (*self).write_byte(cx, b)
230 }
231}
232
233#[cfg(feature = "alloc")]
234impl Writer for rust_alloc::vec::Vec<u8> {
235 type Ok = ();
236 type Mut<'this>
237 = &'this mut Self
238 where
239 Self: 'this;
240
241 #[inline]
242 fn finish<C>(&mut self, _: C) -> Result<Self::Ok, C::Error>
243 where
244 C: Context,
245 {
246 Ok(())
247 }
248
249 #[inline]
250 fn borrow_mut(&mut self) -> Self::Mut<'_> {
251 self
252 }
253
254 #[inline]
255 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
256 where
257 C: Context,
258 {
259 // SAFETY: the buffer never outlives this function call.
260 self.write_bytes(cx, buffer.as_slice())
261 }
262
263 #[inline]
264 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
265 where
266 C: Context,
267 {
268 self.extend_from_slice(bytes);
269 cx.advance(bytes.len());
270 Ok(())
271 }
272
273 #[inline]
274 fn write_byte<C>(&mut self, cx: C, b: u8) -> Result<(), C::Error>
275 where
276 C: Context,
277 {
278 self.push(b);
279 cx.advance(1);
280 Ok(())
281 }
282}
283
284impl<'a> IntoWriter for &'a mut [u8] {
285 type Ok = usize;
286 type Writer = SliceMutWriter<'a>;
287
288 #[inline]
289 fn into_writer(self) -> Self::Writer {
290 SliceMutWriter::new(self)
291 }
292}
293
294/// A writer that writes against an underlying [`Vec`].
295pub struct BufWriter<A>
296where
297 A: Allocator,
298{
299 buf: Vec<u8, A>,
300}
301
302impl<A> BufWriter<A>
303where
304 A: Allocator,
305{
306 /// Construct a new buffer writer.
307 ///
308 /// # Examples
309 ///
310 /// ```
311 /// use musli::alloc::Global;
312 /// use musli::writer::BufWriter;
313 ///
314 /// let writer = BufWriter::new(Global::new());
315 /// ```
316 pub fn new(alloc: A) -> Self {
317 Self {
318 buf: Vec::new_in(alloc),
319 }
320 }
321
322 /// Coerce into inner buffer.
323 ///
324 /// # Examples
325 ///
326 /// ```
327 /// use musli::alloc::Global;
328 /// use musli::writer::BufWriter;
329 ///
330 /// let writer = BufWriter::new(Global::new());
331 /// let buffer = writer.into_inner();
332 /// assert!(buffer.is_empty());
333 /// ```
334 pub fn into_inner(self) -> Vec<u8, A> {
335 self.buf
336 }
337}
338
339impl<A> Writer for BufWriter<A>
340where
341 A: Allocator,
342{
343 type Ok = ();
344 type Mut<'this>
345 = &'this mut Self
346 where
347 Self: 'this;
348
349 #[inline]
350 fn finish<C>(&mut self, _: C) -> Result<Self::Ok, C::Error>
351 where
352 C: Context,
353 {
354 Ok(())
355 }
356
357 #[inline]
358 fn borrow_mut(&mut self) -> Self::Mut<'_> {
359 self
360 }
361
362 #[inline]
363 fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
364 where
365 C: Context,
366 {
367 self.buf
368 .extend_from_slice(buffer.as_slice())
369 .map_err(cx.map())?;
370 Ok(())
371 }
372
373 #[inline]
374 fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
375 where
376 C: Context,
377 {
378 self.buf.extend_from_slice(bytes).map_err(cx.map())?;
379 Ok(())
380 }
381}
382
383/// Overflow when trying to write to a slice.
384#[derive(Debug)]
385struct SliceOverflow {
386 n: usize,
387 capacity: usize,
388}
389
390impl fmt::Display for SliceOverflow {
391 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
392 let SliceOverflow { n, capacity } = self;
393
394 write!(
395 f,
396 "Tried to write {n} bytes to slice, with a remaining capacity of {capacity}"
397 )
398 }
399}