musli_common/
reader.rs

1//! Trait for governing how a particular source of bytes is read.
2//!
3//! `musli` requires all sources to reference the complete data being read from
4//! it which allows it to make the assumption the bytes are always returned with
5//! the `'de` lifetime.
6
7use core::array;
8use core::fmt;
9use core::marker;
10use core::ops::Range;
11use core::ptr;
12use core::slice;
13
14use musli::de::ValueVisitor;
15use musli::Context;
16
17/// Underflow when trying to read from a slice.
18#[derive(Debug)]
19pub(crate) struct SliceUnderflow {
20    n: usize,
21    remaining: usize,
22}
23
24impl fmt::Display for SliceUnderflow {
25    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26        let SliceUnderflow { n, remaining } = self;
27
28        write!(
29            f,
30            "Tried to read {n} bytes from slice, with {remaining} byte remaining"
31        )
32    }
33}
34
35/// Trait governing how a source of bytes is read.
36///
37/// This requires the reader to be able to hand out contiguous references to the
38/// byte source through [Reader::read_bytes].
39pub trait Reader<'de> {
40    /// Type borrowed from self.
41    ///
42    /// Why oh why would we want to do this over having a simple `&'this mut T`?
43    ///
44    /// We want to avoid recursive types, which will blow up the compiler. And
45    /// the above is a typical example of when that can go wrong. This ensures
46    /// that each call to `borrow_mut` dereferences the [Reader] at each step to
47    /// avoid constructing a large muted type, like `&mut &mut &mut
48    /// SliceReader<'de>`.
49    type Mut<'this>: Reader<'de>
50    where
51        Self: 'this;
52
53    /// Borrow the current reader.
54    fn borrow_mut(&mut self) -> Self::Mut<'_>;
55
56    /// Skip over the given number of bytes.
57    fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
58    where
59        C: ?Sized + Context;
60
61    /// Peek the next value.
62    fn peek<C>(&mut self, cx: &C) -> Result<Option<u8>, C::Error>
63    where
64        C: ?Sized + Context;
65
66    /// Read a slice into the given buffer.
67    #[inline]
68    fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
69    where
70        C: ?Sized + Context,
71    {
72        struct Visitor<'a>(&'a mut [u8]);
73
74        impl<'a, 'de, C> ValueVisitor<'de, C, [u8]> for Visitor<'a>
75        where
76            C: ?Sized + Context,
77        {
78            type Ok = ();
79
80            #[inline]
81            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82                write!(f, "bytes")
83            }
84
85            #[inline]
86            fn visit_borrowed(self, cx: &C, bytes: &'de [u8]) -> Result<Self::Ok, C::Error> {
87                self.visit_ref(cx, bytes)
88            }
89
90            #[inline]
91            fn visit_ref(self, _: &C, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
92                self.0.copy_from_slice(bytes);
93                Ok(())
94            }
95        }
96
97        self.read_bytes(cx, buf.len(), Visitor(buf))
98    }
99
100    /// Read a slice out of the current reader.
101    fn read_bytes<C, V>(&mut self, cx: &C, n: usize, visitor: V) -> Result<V::Ok, C::Error>
102    where
103        C: ?Sized + Context,
104        V: ValueVisitor<'de, C, [u8]>;
105
106    /// Read a single byte.
107    #[inline]
108    fn read_byte<C>(&mut self, cx: &C) -> Result<u8, C::Error>
109    where
110        C: ?Sized + Context,
111    {
112        let [byte] = self.read_array::<C, 1>(cx)?;
113        Ok(byte)
114    }
115
116    /// Read an array out of the current reader.
117    #[inline]
118    fn read_array<C, const N: usize>(&mut self, cx: &C) -> Result<[u8; N], C::Error>
119    where
120        C: ?Sized + Context,
121    {
122        struct Visitor<const N: usize>([u8; N]);
123
124        impl<'de, const N: usize, C> ValueVisitor<'de, C, [u8]> for Visitor<N>
125        where
126            C: ?Sized + Context,
127        {
128            type Ok = [u8; N];
129
130            #[inline]
131            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
132                write!(f, "bytes")
133            }
134
135            #[inline]
136            fn visit_borrowed(self, cx: &C, bytes: &'de [u8]) -> Result<Self::Ok, C::Error> {
137                self.visit_ref(cx, bytes)
138            }
139
140            #[inline]
141            fn visit_ref(mut self, cx: &C, bytes: &[u8]) -> Result<Self::Ok, C::Error> {
142                self.0.copy_from_slice(bytes);
143                cx.advance(bytes.len());
144                Ok(self.0)
145            }
146        }
147
148        self.read_bytes(cx, N, Visitor([0u8; N]))
149    }
150
151    /// Keep an accurate record of the position within the reader.
152    fn limit(self, limit: usize) -> Limit<Self>
153    where
154        Self: Sized,
155    {
156        Limit {
157            remaining: limit,
158            reader: self,
159        }
160    }
161}
162
163impl<'de> Reader<'de> for &'de [u8] {
164    type Mut<'this> = &'this mut &'de [u8] where Self: 'this;
165
166    #[inline]
167    fn borrow_mut(&mut self) -> Self::Mut<'_> {
168        self
169    }
170
171    #[inline]
172    fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
173    where
174        C: ?Sized + Context,
175    {
176        if self.len() < n {
177            return Err(cx.message(SliceUnderflow {
178                n,
179                remaining: self.len(),
180            }));
181        }
182
183        let (_, tail) = self.split_at(n);
184        *self = tail;
185        cx.advance(n);
186        Ok(())
187    }
188
189    #[inline]
190    fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
191    where
192        C: ?Sized + Context,
193    {
194        if self.len() < buf.len() {
195            return Err(cx.message("Buffer underflow"));
196        }
197
198        let (head, tail) = self.split_at(buf.len());
199        buf.copy_from_slice(head);
200        *self = tail;
201        cx.advance(buf.len());
202        Ok(())
203    }
204
205    #[inline]
206    fn read_bytes<C, V>(&mut self, cx: &C, n: usize, visitor: V) -> Result<V::Ok, C::Error>
207    where
208        C: ?Sized + Context,
209        V: ValueVisitor<'de, C, [u8]>,
210    {
211        if self.len() < n {
212            return Err(cx.message("Buffer underflow"));
213        }
214
215        let (head, tail) = self.split_at(n);
216        *self = tail;
217        let ok = visitor.visit_borrowed(cx, head)?;
218        cx.advance(n);
219        Ok(ok)
220    }
221
222    #[inline]
223    fn read_byte<C>(&mut self, cx: &C) -> Result<u8, C::Error>
224    where
225        C: ?Sized + Context,
226    {
227        let &[first, ref tail @ ..] = *self else {
228            return Err(cx.message("Buffer underflow"));
229        };
230
231        *self = tail;
232        cx.advance(1);
233        Ok(first)
234    }
235
236    #[inline]
237    fn read_array<C, const N: usize>(&mut self, cx: &C) -> Result<[u8; N], C::Error>
238    where
239        C: ?Sized + Context,
240    {
241        if self.len() < N {
242            return Err(cx.message("Buffer underflow"));
243        }
244
245        let (head, tail) = self.split_at(N);
246        *self = tail;
247        cx.advance(N);
248        Ok(array::from_fn(|n| head[n]))
249    }
250
251    #[inline]
252    fn peek<C>(&mut self, _: &C) -> Result<Option<u8>, C::Error>
253    where
254        C: ?Sized + Context,
255    {
256        Ok(self.first().copied())
257    }
258}
259
260/// An efficient [Reader] wrapper around a slice.
261pub struct SliceReader<'de> {
262    range: Range<*const u8>,
263    _marker: marker::PhantomData<&'de [u8]>,
264}
265
266// SAFETY: `SliceReader` is effectively equivalent to `&'de [u8]`.
267unsafe impl Send for SliceReader<'_> {}
268// SAFETY: `SliceReader` is effectively equivalent to `&'de [u8]`.
269unsafe impl Sync for SliceReader<'_> {}
270
271impl<'de> SliceReader<'de> {
272    /// Construct a new instance around the specified slice.
273    #[inline]
274    pub fn new(slice: &'de [u8]) -> Self {
275        Self {
276            range: slice.as_ptr_range(),
277            _marker: marker::PhantomData,
278        }
279    }
280
281    /// Get the remaining contents of the reader as a slice.
282    ///
283    /// # Examples
284    ///
285    /// ```ignore
286    /// use musli::Context;
287    /// use musli_descriptive::reader::{Reader, SliceReader};
288    ///
289    /// fn process<C>(cx: &C) -> Result<(), C::Error>
290    /// where
291    ///     C: ?Sized + Context
292    /// {
293    ///     let reader = SliceReader::new(&[1, 2, 3, 4]);
294    ///     assert_eq!(reader.as_slice(), &[1, 2, 3, 4]);
295    ///     reader.skip(&cx, 2)?;
296    ///     assert_eq!(reader.as_slice(), &[3, 4]);
297    ///     Ok(())
298    /// }
299    /// ```
300    pub fn as_slice(&self) -> &'de [u8] {
301        unsafe { slice::from_raw_parts(self.range.start, self.remaining()) }
302    }
303
304    /// Get remaining bytes in the reader.
305    ///
306    /// # Examples
307    ///
308    /// ```ignore
309    /// use musli::Context;
310    /// use musli_descriptive::reader::{Reader, SliceReader};
311    ///
312    /// fn process<C>(cx: &C) -> Result<(), C::Error>
313    /// where
314    ///     C: ?Sized + Context
315    /// {
316    ///     let reader = SliceReader::new(&[1, 2, 3, 4]);
317    ///     assert_eq!(reader.remaining(), 4);
318    ///     reader.skip(&cx, 2);
319    ///     assert_eq!(reader.remaining(), 2);
320    ///     Ok(())
321    /// }
322    /// ```
323    pub fn remaining(&self) -> usize {
324        self.range.end as usize - self.range.start as usize
325    }
326}
327
328impl<'de> Reader<'de> for SliceReader<'de> {
329    type Mut<'this> = &'this mut Self where Self: 'this;
330
331    #[inline]
332    fn borrow_mut(&mut self) -> Self::Mut<'_> {
333        self
334    }
335
336    #[inline]
337    fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
338    where
339        C: ?Sized + Context,
340    {
341        self.range.start = bounds_check_add(cx, &self.range, n)?;
342        cx.advance(n);
343        Ok(())
344    }
345
346    #[inline]
347    fn read_bytes<C, V>(&mut self, cx: &C, n: usize, visitor: V) -> Result<V::Ok, C::Error>
348    where
349        C: ?Sized + Context,
350        V: ValueVisitor<'de, C, [u8]>,
351    {
352        let outcome = bounds_check_add(cx, &self.range, n)?;
353
354        let ok = unsafe {
355            let bytes = slice::from_raw_parts(self.range.start, n);
356            self.range.start = outcome;
357            visitor.visit_borrowed(cx, bytes)?
358        };
359
360        cx.advance(n);
361        Ok(ok)
362    }
363
364    #[inline]
365    fn peek<C>(&mut self, _: &C) -> Result<Option<u8>, C::Error>
366    where
367        C: ?Sized + Context,
368    {
369        if self.range.start == self.range.end {
370            return Ok(None);
371        }
372
373        // SAFETY: we've checked that the elements are in bound above.
374        unsafe { Ok(Some(ptr::read(self.range.start))) }
375    }
376
377    #[inline]
378    fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
379    where
380        C: ?Sized + Context,
381    {
382        let outcome = bounds_check_add(cx, &self.range, buf.len())?;
383
384        unsafe {
385            ptr::copy_nonoverlapping(self.range.start, buf.as_mut_ptr(), buf.len());
386            self.range.start = outcome;
387        }
388
389        cx.advance(buf.len());
390        Ok(())
391    }
392}
393
394#[inline]
395fn bounds_check_add<C>(cx: &C, range: &Range<*const u8>, len: usize) -> Result<*const u8, C::Error>
396where
397    C: ?Sized + Context,
398{
399    let outcome = range.start.wrapping_add(len);
400
401    if outcome > range.end || outcome < range.start {
402        Err(cx.message(SliceUnderflow {
403            n: len,
404            remaining: (range.end as usize).wrapping_sub(range.start as usize),
405        }))
406    } else {
407        Ok(outcome)
408    }
409}
410
411/// Limit the number of bytes that can be read out of a reader to the specified limit.
412///
413/// Constructed through [Reader::limit].
414pub struct Limit<R> {
415    remaining: usize,
416    reader: R,
417}
418
419impl<R> Limit<R> {
420    /// Get the remaining data in the limited reader.
421    pub fn remaining(&self) -> usize {
422        self.remaining
423    }
424}
425
426impl<'de, R> Limit<R>
427where
428    R: Reader<'de>,
429{
430    fn bounds_check<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
431    where
432        C: ?Sized + Context,
433    {
434        match self.remaining.checked_sub(n) {
435            Some(remaining) => {
436                self.remaining = remaining;
437                Ok(())
438            }
439            None => Err(cx.message("Reader out of bounds")),
440        }
441    }
442}
443
444impl<'de, R> Reader<'de> for Limit<R>
445where
446    R: Reader<'de>,
447{
448    type Mut<'this> = &'this mut Self where Self: 'this;
449
450    #[inline]
451    fn borrow_mut(&mut self) -> Self::Mut<'_> {
452        self
453    }
454
455    #[inline]
456    fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
457    where
458        C: ?Sized + Context,
459    {
460        self.bounds_check(cx, n)?;
461        self.reader.skip(cx, n)
462    }
463
464    #[inline]
465    fn read_bytes<C, V>(&mut self, cx: &C, n: usize, visitor: V) -> Result<V::Ok, C::Error>
466    where
467        C: ?Sized + Context,
468        V: ValueVisitor<'de, C, [u8]>,
469    {
470        self.bounds_check(cx, n)?;
471        self.reader.read_bytes(cx, n, visitor)
472    }
473
474    #[inline]
475    fn peek<C>(&mut self, cx: &C) -> Result<Option<u8>, C::Error>
476    where
477        C: ?Sized + Context,
478    {
479        self.reader.peek(cx)
480    }
481
482    #[inline]
483    fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
484    where
485        C: ?Sized + Context,
486    {
487        self.bounds_check(cx, buf.len())?;
488        self.reader.read(cx, buf)
489    }
490
491    #[inline]
492    fn read_byte<C>(&mut self, cx: &C) -> Result<u8, C::Error>
493    where
494        C: ?Sized + Context,
495    {
496        self.bounds_check(cx, 1)?;
497        self.reader.read_byte(cx)
498    }
499
500    #[inline]
501    fn read_array<C, const N: usize>(&mut self, cx: &C) -> Result<[u8; N], C::Error>
502    where
503        C: ?Sized + Context,
504    {
505        self.bounds_check(cx, N)?;
506        self.reader.read_array(cx)
507    }
508}
509
510// Forward implementations.
511
512impl<'de, R> Reader<'de> for &mut R
513where
514    R: ?Sized + Reader<'de>,
515{
516    type Mut<'this> = &'this mut R where Self: 'this;
517
518    #[inline]
519    fn borrow_mut(&mut self) -> Self::Mut<'_> {
520        self
521    }
522
523    #[inline]
524    fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
525    where
526        C: ?Sized + Context,
527    {
528        (**self).skip(cx, n)
529    }
530
531    #[inline]
532    fn read_bytes<C, V>(&mut self, cx: &C, n: usize, visitor: V) -> Result<V::Ok, C::Error>
533    where
534        C: ?Sized + Context,
535        V: ValueVisitor<'de, C, [u8]>,
536    {
537        (**self).read_bytes(cx, n, visitor)
538    }
539
540    #[inline]
541    fn peek<C>(&mut self, cx: &C) -> Result<Option<u8>, C::Error>
542    where
543        C: ?Sized + Context,
544    {
545        (**self).peek(cx)
546    }
547
548    #[inline]
549    fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
550    where
551        C: ?Sized + Context,
552    {
553        (**self).read(cx, buf)
554    }
555
556    #[inline]
557    fn read_byte<C>(&mut self, cx: &C) -> Result<u8, C::Error>
558    where
559        C: ?Sized + Context,
560    {
561        (**self).read_byte(cx)
562    }
563
564    #[inline]
565    fn read_array<C, const N: usize>(&mut self, cx: &C) -> Result<[u8; N], C::Error>
566    where
567        C: ?Sized + Context,
568    {
569        (**self).read_array(cx)
570    }
571}