musli_core/
expecting.rs

1//! Internal helpers for generating nice expectation messages.
2
3use core::fmt::{self, Display};
4
5use crate::de::SizeHint;
6
7pub trait Expecting {
8    /// Generated the actual message of what we expected.
9    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result;
10
11    /// Return a type that can be formatted from `self`.
12    #[doc(hidden)]
13    fn format(&self) -> &dyn Expecting
14    where
15        Self: Sized,
16    {
17        self
18    }
19}
20
21impl Expecting for str {
22    #[inline]
23    fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        self.fmt(f)
25    }
26}
27
28impl fmt::Display for &dyn Expecting {
29    #[inline]
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        self.expecting(f)
32    }
33}
34
35struct FormatFn<T>(T);
36
37impl<T> fmt::Display for FormatFn<T>
38where
39    T: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
40{
41    #[inline]
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        (self.0)(f)
44    }
45}
46
47#[inline]
48fn format_fn<T>(function: T) -> FormatFn<T>
49where
50    T: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
51{
52    FormatFn(function)
53}
54
55/// Format an invalid type message.
56pub(crate) fn unsupported_type<'a>(
57    actual: &'a dyn fmt::Display,
58    expected: &'a dyn Expecting,
59) -> impl fmt::Display + 'a {
60    format_fn(move |f| {
61        write! {
62            f,
63            "Got unsupported type `{actual}`, but expected {expected}"
64        }
65    })
66}
67
68/// Format a bad visitor type message.
69pub(crate) fn bad_visitor_type<'a>(
70    actual: &'a dyn fmt::Display,
71    expected: &'a dyn Expecting,
72) -> impl fmt::Display + 'a {
73    format_fn(move |f| {
74        write! {
75            f,
76            "Bad reference type {actual}, expected {expected}",
77        }
78    })
79}
80
81macro_rules! expect_with {
82    ($($vis:vis $ident:ident($string:literal, $ty:ty);)*) => {
83        $(
84            $vis struct $ident($vis $ty);
85
86            impl fmt::Display for $ident {
87                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88                    write!(f, $string, self.0)
89                }
90            }
91        )*
92    }
93}
94
95macro_rules! expect {
96    ($($vis:vis $ident:ident($string:literal);)*) => {
97        $(
98            $vis struct $ident;
99
100            impl fmt::Display for $ident {
101                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102                    write!(f, $string)
103                }
104            }
105        )*
106    }
107}
108
109expect_with! {
110    pub(crate) SequenceWith("sequence with {0}", SizeHint);
111    pub(crate) MapWith("map with {0}", SizeHint);
112    pub(crate) BytesWith("bytes with {0}", SizeHint);
113    pub(crate) StringWith("string with {0}", SizeHint);
114}
115
116expect! {
117    pub(crate) Any("a dynamic value");
118    pub(crate) Empty("empty");
119    pub(crate) Option("option");
120    pub(crate) Pack("pack");
121    pub(crate) Bool("boolean");
122    pub(crate) Char("character");
123    pub(crate) Number("arbitrary precision number");
124    pub(crate) Unsigned8("8-bit unsigned integer");
125    pub(crate) Unsigned16("16-bit unsigned integer");
126    pub(crate) Unsigned32("32-bit unsigned integer");
127    pub(crate) Unsigned64("64-bit unsigned integer");
128    pub(crate) Unsigned128("128-bit unsigned integer");
129    pub(crate) Signed8("8-bit signed integer");
130    pub(crate) Signed16("16-bit signed integer");
131    pub(crate) Signed32("32-bit signed integer");
132    pub(crate) Signed64("64-bit signed integer");
133    pub(crate) Signed128("128-bit signed integer");
134    pub(crate) Float32("32-bit float");
135    pub(crate) Float64("64-bit float");
136    pub(crate) Isize("isize");
137    pub(crate) Usize("usize");
138    pub(crate) String("string");
139    pub(crate) CollectString("collected string");
140    pub(crate) Bytes("bytes");
141    pub(crate) Array("array");
142    pub(crate) Map("map");
143    pub(crate) MapEntries("map entries");
144    pub(crate) UnsizedMap("unsized map");
145    pub(crate) MapVariant("map variant");
146    pub(crate) UnsizedSequence("unsized sequence");
147    pub(crate) SequenceVariant("sequence variant");
148    pub(crate) Variant("variant");
149    pub(crate) AnyValue("a value");
150}