musli_core/de/
visitor.rs

1use core::fmt;
2use core::marker::PhantomData;
3
4use crate::expecting::{self, Expecting};
5use crate::{Allocator, Context};
6
7use super::{Decoder, MapDecoder, SequenceDecoder, SizeHint, UnsizedVisitor, VariantDecoder};
8
9/// Visitor capable of decoding any type into a value [`Visitor::Ok`].
10///
11/// When implementing this trait you must use the `#[musli::trait_defaults]`
12/// attribute macro.
13///
14/// Each callback on this visitor indicates the type that should be decoded from
15/// the passed in decoder. A typical implementation would simply call the
16/// corresponding decoder function for the type being visited.
17///
18/// # Examples
19///
20/// ```
21/// use std::fmt;
22///
23/// use musli::Context;
24/// use musli::de::Visitor;
25///
26/// struct AnyVisitor;
27///
28/// #[musli::trait_defaults]
29/// impl<'de, C> Visitor<'de, C> for AnyVisitor
30/// where
31///     C: Context,
32/// {
33///     type Ok = ();
34///
35///     #[inline]
36///     fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37///         write!(f, "a value that can be decoded into dynamic container")
38///     }
39/// }
40/// ```
41pub trait Visitor<'de, C>: Sized
42where
43    C: Context<Error = Self::Error, Allocator = Self::Allocator>,
44{
45    /// The value produced by the visitor.
46    type Ok;
47    /// The error produced by the visitor.
48    type Error;
49    /// The allocator associated with the visitor.
50    type Allocator: Allocator;
51    /// String decoder to use.
52    type String: UnsizedVisitor<'de, C, str, Ok = Self::Ok, Error = Self::Error, Allocator = Self::Allocator>;
53    /// Bytes decoder to use.
54    type Bytes: UnsizedVisitor<
55            'de,
56            C,
57            [u8],
58            Ok = Self::Ok,
59            Error = Self::Error,
60            Allocator = Self::Allocator,
61        >;
62
63    /// This is a type argument used to hint to any future implementor that they
64    /// should be using the `#[musli::trait_defaults]`.
65    #[doc(hidden)]
66    type __UseMusliVisitorAttributeMacro;
67
68    /// Format the human-readable message that should occur if the decoder was
69    /// expecting to decode some specific kind of value.
70    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
71
72    /// Indicates that the visited type is empty.
73    #[inline]
74    fn visit_empty(self, cx: C) -> Result<Self::Ok, Self::Error> {
75        Err(cx.message(expecting::unsupported_type(
76            &expecting::Empty,
77            ExpectingWrapper::new(&self),
78        )))
79    }
80
81    /// Indicates that the visited type is a `bool`.
82    #[inline]
83    fn visit_bool(self, cx: C, _: bool) -> Result<Self::Ok, Self::Error> {
84        Err(cx.message(expecting::unsupported_type(
85            &expecting::Bool,
86            ExpectingWrapper::new(&self),
87        )))
88    }
89
90    /// Indicates that the visited type is a `char`.
91    #[inline]
92    fn visit_char(self, cx: C, _: char) -> Result<Self::Ok, Self::Error> {
93        Err(cx.message(expecting::unsupported_type(
94            &expecting::Char,
95            ExpectingWrapper::new(&self),
96        )))
97    }
98
99    /// Indicates that the visited type is a `u8`.
100    #[inline]
101    fn visit_u8(self, cx: C, _: u8) -> Result<Self::Ok, Self::Error> {
102        Err(cx.message(expecting::unsupported_type(
103            &expecting::Unsigned8,
104            ExpectingWrapper::new(&self),
105        )))
106    }
107
108    /// Indicates that the visited type is a `u16`.
109    #[inline]
110    fn visit_u16(self, cx: C, _: u16) -> Result<Self::Ok, Self::Error> {
111        Err(cx.message(expecting::unsupported_type(
112            &expecting::Unsigned16,
113            ExpectingWrapper::new(&self),
114        )))
115    }
116
117    /// Indicates that the visited type is a `u32`.
118    #[inline]
119    fn visit_u32(self, cx: C, _: u32) -> Result<Self::Ok, Self::Error> {
120        Err(cx.message(expecting::unsupported_type(
121            &expecting::Unsigned32,
122            ExpectingWrapper::new(&self),
123        )))
124    }
125
126    /// Indicates that the visited type is a `u64`.
127    #[inline]
128    fn visit_u64(self, cx: C, _: u64) -> Result<Self::Ok, Self::Error> {
129        Err(cx.message(expecting::unsupported_type(
130            &expecting::Unsigned64,
131            ExpectingWrapper::new(&self),
132        )))
133    }
134
135    /// Indicates that the visited type is a `u128`.
136    #[inline]
137    fn visit_u128(self, cx: C, _: u128) -> Result<Self::Ok, Self::Error> {
138        Err(cx.message(expecting::unsupported_type(
139            &expecting::Unsigned128,
140            ExpectingWrapper::new(&self),
141        )))
142    }
143
144    /// Indicates that the visited type is a `i8`.
145    #[inline]
146    fn visit_i8(self, cx: C, _: i8) -> Result<Self::Ok, Self::Error> {
147        Err(cx.message(expecting::unsupported_type(
148            &expecting::Signed8,
149            ExpectingWrapper::new(&self),
150        )))
151    }
152
153    /// Indicates that the visited type is a `i16`.
154    #[inline]
155    fn visit_i16(self, cx: C, _: i16) -> Result<Self::Ok, Self::Error> {
156        Err(cx.message(expecting::unsupported_type(
157            &expecting::Signed16,
158            ExpectingWrapper::new(&self),
159        )))
160    }
161
162    /// Indicates that the visited type is a `i32`.
163    #[inline]
164    fn visit_i32(self, cx: C, _: i32) -> Result<Self::Ok, Self::Error> {
165        Err(cx.message(expecting::unsupported_type(
166            &expecting::Signed32,
167            ExpectingWrapper::new(&self),
168        )))
169    }
170
171    /// Indicates that the visited type is a `i64`.
172    #[inline]
173    fn visit_i64(self, cx: C, _: i64) -> Result<Self::Ok, Self::Error> {
174        Err(cx.message(expecting::unsupported_type(
175            &expecting::Signed64,
176            ExpectingWrapper::new(&self),
177        )))
178    }
179
180    /// Indicates that the visited type is a `i128`.
181    #[inline]
182    fn visit_i128(self, cx: C, _: i128) -> Result<Self::Ok, Self::Error> {
183        Err(cx.message(expecting::unsupported_type(
184            &expecting::Signed128,
185            ExpectingWrapper::new(&self),
186        )))
187    }
188
189    /// Indicates that the visited type is a `usize`.
190    #[inline]
191    fn visit_usize(self, cx: C, _: usize) -> Result<Self::Ok, Self::Error> {
192        Err(cx.message(expecting::unsupported_type(
193            &expecting::Usize,
194            ExpectingWrapper::new(&self),
195        )))
196    }
197
198    /// Indicates that the visited type is a `isize`.
199    #[inline]
200    fn visit_isize(self, cx: C, _: isize) -> Result<Self::Ok, Self::Error> {
201        Err(cx.message(expecting::unsupported_type(
202            &expecting::Isize,
203            ExpectingWrapper::new(&self),
204        )))
205    }
206
207    /// Indicates that the visited type is a `f32`.
208    #[inline]
209    fn visit_f32(self, cx: C, _: f32) -> Result<Self::Ok, Self::Error> {
210        Err(cx.message(expecting::unsupported_type(
211            &expecting::Float32,
212            ExpectingWrapper::new(&self),
213        )))
214    }
215
216    /// Indicates that the visited type is a `f64`.
217    #[inline]
218    fn visit_f64(self, cx: C, _: f64) -> Result<Self::Ok, Self::Error> {
219        Err(cx.message(expecting::unsupported_type(
220            &expecting::Float64,
221            ExpectingWrapper::new(&self),
222        )))
223    }
224
225    /// Indicates that the visited type is an optional value that is absent.
226    #[inline]
227    fn visit_none(self, cx: C) -> Result<Self::Ok, Self::Error> {
228        Err(cx.message(expecting::unsupported_type(
229            &expecting::Option,
230            ExpectingWrapper::new(&self),
231        )))
232    }
233
234    /// Indicates that the visited type is an optional value that is present.
235    #[inline]
236    fn visit_some<D>(self, decoder: D) -> Result<Self::Ok, Self::Error>
237    where
238        D: Decoder<'de, Cx = C, Error = C::Error, Allocator = C::Allocator>,
239    {
240        Err(decoder.cx().message(expecting::unsupported_type(
241            &expecting::Option,
242            ExpectingWrapper::new(&self),
243        )))
244    }
245
246    /// Indicates that the visited type is a sequence.
247    #[inline]
248    fn visit_sequence<D>(self, decoder: &mut D) -> Result<Self::Ok, Self::Error>
249    where
250        D: ?Sized + SequenceDecoder<'de, Cx = C, Error = Self::Error, Allocator = Self::Allocator>,
251    {
252        Err(decoder.cx().message(expecting::unsupported_type(
253            &expecting::SequenceWith(decoder.size_hint()),
254            ExpectingWrapper::new(&self),
255        )))
256    }
257
258    /// Indicates that the visited type is a map.
259    #[inline]
260    fn visit_map<D>(self, decoder: &mut D) -> Result<Self::Ok, Self::Error>
261    where
262        D: ?Sized + MapDecoder<'de, Cx = C, Error = Self::Error, Allocator = Self::Allocator>,
263    {
264        Err(decoder.cx().message(expecting::unsupported_type(
265            &expecting::MapWith(decoder.size_hint()),
266            ExpectingWrapper::new(&self),
267        )))
268    }
269
270    /// Indicates that the visited type is `string`.
271    #[inline]
272    fn visit_string(self, cx: C, hint: SizeHint) -> Result<Self::String, Self::Error> {
273        Err(cx.message(expecting::unsupported_type(
274            &expecting::StringWith(hint),
275            ExpectingWrapper::new(&self),
276        )))
277    }
278
279    /// Indicates that the visited type is `bytes`.
280    #[inline]
281    fn visit_bytes(self, cx: C, hint: SizeHint) -> Result<Self::Bytes, Self::Error> {
282        Err(cx.message(expecting::unsupported_type(
283            &expecting::BytesWith(hint),
284            ExpectingWrapper::new(&self),
285        )))
286    }
287
288    /// Indicates that the visited type is a variant.
289    #[inline]
290    fn visit_variant<D>(self, decoder: &mut D) -> Result<Self::Ok, Self::Error>
291    where
292        D: ?Sized + VariantDecoder<'de, Cx = C, Error = C::Error, Allocator = C::Allocator>,
293    {
294        Err(decoder.cx().message(expecting::unsupported_type(
295            &expecting::Variant,
296            ExpectingWrapper::new(&self),
297        )))
298    }
299
300    /// Indicates that the encoding does not support dynamic types.
301    #[inline]
302    fn visit_unknown<D>(self, decoder: D) -> Result<Self::Ok, D::Error>
303    where
304        D: Decoder<'de, Cx = C, Error = C::Error, Allocator = C::Allocator>,
305    {
306        Err(decoder.cx().message(expecting::unsupported_type(
307            &expecting::Any,
308            ExpectingWrapper::new(&self),
309        )))
310    }
311}
312
313#[repr(transparent)]
314struct ExpectingWrapper<T, C> {
315    inner: T,
316    _marker: PhantomData<C>,
317}
318
319impl<T, C> ExpectingWrapper<T, C> {
320    fn new(inner: &T) -> &Self {
321        // SAFETY: `ExpectingWrapper` is repr(transparent) over `T`.
322        unsafe { &*(inner as *const T as *const Self) }
323    }
324}
325
326impl<'de, T, C> Expecting for ExpectingWrapper<T, C>
327where
328    C: Context,
329    T: Visitor<'de, C, Error = C::Error, Allocator = C::Allocator>,
330{
331    #[inline]
332    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333        self.inner.expecting(f)
334    }
335}