musli_core/de/
visitor.rs

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