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`].
26pub trait IntoWriter
27where
28    Self: self::sealed::Sealed,
29{
30    /// The output of the writer which will be returned after writing.
31    type Ok;
32
33    /// The writer type.
34    type Writer: Writer<Ok = Self::Ok>;
35
36    /// Convert the type into a writer.
37    fn into_writer(self) -> Self::Writer;
38}
39
40/// The trait governing how a writer works.
41pub trait Writer {
42    /// The value returned from writing the value.
43    type Ok;
44
45    /// Reborrowed type.
46    ///
47    /// Why oh why would we want to do this over having a simple `&'this mut T`?
48    ///
49    /// We want to avoid recursive types, which will blow up the compiler. And
50    /// the above is a typical example of when that can go wrong. This ensures
51    /// that each call to `borrow_mut` dereferences the [`Reader`] at each step to
52    /// avoid constructing a large muted type, like `&mut &mut &mut VecWriter`.
53    ///
54    /// [`Reader`]: crate::reader::Reader
55    type Mut<'this>: Writer
56    where
57        Self: 'this;
58
59    /// Finalize the writer and return the output.
60    fn finish<C>(&mut self, cx: C) -> Result<Self::Ok, C::Error>
61    where
62        C: Context;
63
64    /// Reborrow the current type.
65    fn borrow_mut(&mut self) -> Self::Mut<'_>;
66
67    /// Write a buffer to the current writer.
68    fn extend<C>(&mut self, cx: C, buffer: Vec<u8, C::Allocator>) -> Result<(), C::Error>
69    where
70        C: Context;
71
72    /// Write bytes to the current writer.
73    fn write_bytes<C>(&mut self, cx: C, bytes: &[u8]) -> Result<(), C::Error>
74    where
75        C: Context;
76
77    /// Write a single byte.
78    #[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        // SAFETY: the buffer never outlives this function call.
175        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
209/// A writer that writes against an underlying [`Vec`].
210pub 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    /// Construct a new buffer writer.
222    pub fn new(alloc: A) -> Self {
223        Self {
224            buf: Vec::new_in(alloc),
225        }
226    }
227
228    /// Coerce into inner buffer.
229    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/// Overflow when trying to write to a slice.
279#[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}