musli_utils/
writer.rs

1//! Trait for governing how a particular sink of bytes is written to.
2//!
3//! To adapt [std::io::Write] types, see the [wrap][crate::wrap::wrap] function.
4
5use core::fmt;
6use core::mem::take;
7
8use musli::{Buf, Context};
9
10#[cfg(feature = "alloc")]
11use alloc::vec::Vec;
12
13/// Maximum size used by a fixed length [`Buf`].
14pub const MAX_FIXED_BYTES_LEN: usize = 128;
15
16/// Overflow when trying to write to a slice.
17#[derive(Debug)]
18pub(crate) struct SliceOverflow {
19    n: usize,
20    capacity: usize,
21}
22
23impl fmt::Display for SliceOverflow {
24    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25        let SliceOverflow { n, capacity } = self;
26
27        write!(
28            f,
29            "Tried to write {n} bytes to slice, with a remaining capacity of {capacity}"
30        )
31    }
32}
33
34/// The trait governing how a writer works.
35pub trait Writer {
36    /// Reborrowed type.
37    ///
38    /// Why oh why would we want to do this over having a simple `&'this mut T`?
39    ///
40    /// We want to avoid recursive types, which will blow up the compiler. And
41    /// the above is a typical example of when that can go wrong. This ensures
42    /// that each call to `borrow_mut` dereferences the [`Reader`] at each step to
43    /// avoid constructing a large muted type, like `&mut &mut &mut VecWriter`.
44    ///
45    /// [`Reader`]: crate::reader::Reader
46    type Mut<'this>: Writer
47    where
48        Self: 'this;
49
50    /// Reborrow the current type.
51    fn borrow_mut(&mut self) -> Self::Mut<'_>;
52
53    /// Write a buffer to the current writer.
54    fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
55    where
56        C: ?Sized + Context,
57        B: Buf;
58
59    /// Write bytes to the current writer.
60    fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
61    where
62        C: ?Sized + Context;
63
64    /// Write a single byte.
65    #[inline]
66    fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
67    where
68        C: ?Sized + Context,
69    {
70        self.write_bytes(cx, &[b])
71    }
72}
73
74impl<W> Writer for &mut W
75where
76    W: ?Sized + Writer,
77{
78    type Mut<'this> = &'this mut W where Self: 'this;
79
80    #[inline]
81    fn borrow_mut(&mut self) -> Self::Mut<'_> {
82        self
83    }
84
85    #[inline]
86    fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
87    where
88        C: ?Sized + Context,
89        B: Buf,
90    {
91        (*self).write_buffer(cx, buffer)
92    }
93
94    #[inline]
95    fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
96    where
97        C: ?Sized + Context,
98    {
99        (*self).write_bytes(cx, bytes)
100    }
101
102    #[inline]
103    fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
104    where
105        C: ?Sized + Context,
106    {
107        (*self).write_byte(cx, b)
108    }
109}
110
111#[cfg(feature = "alloc")]
112impl Writer for Vec<u8> {
113    type Mut<'this> = &'this mut Self where Self: 'this;
114
115    #[inline]
116    fn borrow_mut(&mut self) -> Self::Mut<'_> {
117        self
118    }
119
120    #[inline]
121    fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
122    where
123        C: ?Sized + Context,
124        B: Buf,
125    {
126        // SAFETY: the buffer never outlives this function call.
127        self.write_bytes(cx, buffer.as_slice())
128    }
129
130    #[inline]
131    fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
132    where
133        C: ?Sized + Context,
134    {
135        self.extend_from_slice(bytes);
136        cx.advance(bytes.len());
137        Ok(())
138    }
139
140    #[inline]
141    fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
142    where
143        C: ?Sized + Context,
144    {
145        self.push(b);
146        cx.advance(1);
147        Ok(())
148    }
149}
150
151impl Writer for &mut [u8] {
152    type Mut<'this> = &'this mut Self where Self: 'this;
153
154    #[inline]
155    fn borrow_mut(&mut self) -> Self::Mut<'_> {
156        self
157    }
158
159    #[inline]
160    fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
161    where
162        C: ?Sized + Context,
163        B: Buf,
164    {
165        // SAFETY: the buffer never outlives this function call.
166        self.write_bytes(cx, buffer.as_slice())
167    }
168
169    #[inline]
170    fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
171    where
172        C: ?Sized + Context,
173    {
174        if self.len() < bytes.len() {
175            return Err(cx.message(SliceOverflow {
176                n: bytes.len(),
177                capacity: self.len(),
178            }));
179        }
180
181        let next = take(self);
182        let (this, next) = next.split_at_mut(bytes.len());
183        this.copy_from_slice(bytes);
184        *self = next;
185        Ok(())
186    }
187
188    #[inline]
189    fn write_byte<C>(&mut self, cx: &C, b: u8) -> Result<(), C::Error>
190    where
191        C: ?Sized + Context,
192    {
193        if self.is_empty() {
194            return Err(cx.message(format_args!(
195                "Buffer overflow, remaining is {} while tried to write 1",
196                self.len()
197            )));
198        }
199
200        self[0] = b;
201        *self = &mut take(self)[1..];
202        Ok(())
203    }
204}
205
206/// A writer that writes against an underlying [`Buf`].
207pub struct BufWriter<T> {
208    buf: T,
209}
210
211impl<T> BufWriter<T> {
212    /// Construct a new buffer writer.
213    pub fn new(buf: T) -> Self {
214        Self { buf }
215    }
216
217    /// Coerce into inner buffer.
218    pub fn into_inner(self) -> T {
219        self.buf
220    }
221}
222
223impl<T> Writer for BufWriter<T>
224where
225    T: Buf,
226{
227    type Mut<'this> = &'this mut Self
228    where
229        Self: 'this;
230
231    #[inline(always)]
232    fn borrow_mut(&mut self) -> Self::Mut<'_> {
233        self
234    }
235
236    #[inline(always)]
237    fn write_buffer<C, B>(&mut self, cx: &C, buffer: B) -> Result<(), C::Error>
238    where
239        C: ?Sized + Context,
240        B: Buf,
241    {
242        if !self.buf.write(buffer.as_slice()) {
243            return Err(cx.message("Buffer overflow"));
244        }
245
246        Ok(())
247    }
248
249    #[inline(always)]
250    fn write_bytes<C>(&mut self, cx: &C, bytes: &[u8]) -> Result<(), C::Error>
251    where
252        C: ?Sized + Context,
253    {
254        if !self.buf.write(bytes) {
255            return Err(cx.message("Buffer overflow"));
256        }
257
258        Ok(())
259    }
260}