musli_core/de/
unsized_visitor.rs

1use core::borrow::Borrow;
2use core::fmt;
3use core::marker::PhantomData;
4
5use crate::expecting::{self, Expecting};
6use crate::no_std::ToOwned;
7use crate::Context;
8
9/// A visitor for data where we might need to borrow without copying from the
10/// underlying [`Decoder`].
11///
12/// A visitor is needed with [`Decoder::decode_bytes`] and
13/// [`Decoder::decode_string`] because the caller doesn't know if the encoding
14/// format is capable of producing references to the underlying data directly or
15/// if it needs to be processed first.
16///
17/// If all you want is to decode a value by reference, use the
18/// [`Decoder::decode_unsized`] method.
19///
20/// By requiring a visitor we ensure that the caller has to handle both
21/// scenarios, even if one involves erroring. A type like [Cow] is an example of
22/// a type which can comfortably handle both.
23///
24/// [Cow]: std::borrow::Cow
25/// [`Decoder`]: crate::de::Decoder
26/// [`Decoder::decode_bytes`]: crate::de::Decoder::decode_bytes
27/// [`Decoder::decode_string`]: crate::de::Decoder::decode_string
28/// [`Decoder::decode_unsized`]: crate::de::Decoder::decode_unsized
29pub trait UnsizedVisitor<'de, C: ?Sized + Context, T>: Sized
30where
31    T: ?Sized + ToOwned,
32{
33    /// The value produced.
34    type Ok;
35
36    /// Format an error indicating what was expected by this visitor.
37    ///
38    /// Override to be more specific about the type that failed.
39    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
40
41    /// Visit an owned value.
42    #[inline]
43    fn visit_owned(self, cx: &C, value: T::Owned) -> Result<Self::Ok, C::Error> {
44        self.visit_ref(cx, value.borrow())
45    }
46
47    /// Visit a string that is borrowed directly from the source data.
48    #[inline]
49    fn visit_borrowed(self, cx: &C, value: &'de T) -> Result<Self::Ok, C::Error> {
50        self.visit_ref(cx, value)
51    }
52
53    /// Visit a value reference that is provided from the decoder in any manner
54    /// possible. Which might require additional decoding work.
55    #[inline]
56    fn visit_ref(self, cx: &C, _: &T) -> Result<Self::Ok, C::Error> {
57        Err(cx.message(expecting::bad_visitor_type(
58            &expecting::AnyValue,
59            ExpectingWrapper::new(&self),
60        )))
61    }
62}
63
64#[repr(transparent)]
65struct ExpectingWrapper<'a, T, C: ?Sized, I: ?Sized> {
66    inner: T,
67    _marker: PhantomData<(&'a C, &'a I)>,
68}
69
70impl<'a, T, C: ?Sized, U: ?Sized> ExpectingWrapper<'a, T, C, U> {
71    #[inline]
72    fn new(value: &T) -> &Self {
73        // SAFETY: `ExpectingWrapper` is repr(transparent) over `T`.
74        unsafe { &*(value as *const T as *const Self) }
75    }
76}
77
78impl<'a, 'de, T, C, U> Expecting for ExpectingWrapper<'a, T, C, U>
79where
80    T: UnsizedVisitor<'de, C, U>,
81    C: ?Sized + Context,
82    U: ?Sized + ToOwned,
83{
84    #[inline]
85    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86        self.inner.expecting(f)
87    }
88}