json_syntax/serde/de/
number.rs1use crate::{JsonNumber, JsonNumberBuf, serde::NUMBER_TOKEN};
2use de::{Deserialize, Deserializer};
3use serde::{
4 de::{self, value::StrDeserializer},
5 forward_to_deserialize_any,
6};
7use std::fmt;
8
9impl<'de> Deserialize<'de> for JsonNumberBuf {
10 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
11 where
12 D: Deserializer<'de>,
13 {
14 deserializer.deserialize_any(JsonNumberVisitor)
15 }
16}
17
18pub struct JsonNumberVisitor;
20
21impl<'de> de::Visitor<'de> for JsonNumberVisitor {
22 type Value = JsonNumberBuf;
23
24 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
25 formatter.write_str("JSON number")
26 }
27
28 #[inline]
29 fn visit_u64<E: de::Error>(self, value: u64) -> Result<JsonNumberBuf, E> {
30 Ok(value.into())
31 }
32
33 #[inline]
34 fn visit_i64<E: de::Error>(self, value: i64) -> Result<JsonNumberBuf, E> {
35 Ok(value.into())
36 }
37
38 #[inline]
39 fn visit_f64<E: de::Error>(self, value: f64) -> Result<JsonNumberBuf, E> {
40 JsonNumberBuf::try_from(value)
41 .map_err(|_| E::invalid_value(de::Unexpected::Float(value), &self))
42 }
43
44 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
45 where
46 A: de::MapAccess<'de>,
47 {
48 struct Key;
49
50 impl<'de> Deserialize<'de> for Key {
51 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
52 where
53 D: Deserializer<'de>,
54 {
55 struct KeyVisitor;
56
57 impl<'de> de::Visitor<'de> for KeyVisitor {
58 type Value = Key;
59
60 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
61 formatter.write_str("a valid number field")
62 }
63
64 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
65 where
66 E: de::Error,
67 {
68 if v == NUMBER_TOKEN {
69 Ok(Key)
70 } else {
71 Err(serde::de::Error::custom("expected field with custom name"))
72 }
73 }
74 }
75
76 deserializer.deserialize_identifier(KeyVisitor)
77 }
78 }
79
80 struct Value(JsonNumberBuf);
81
82 impl<'de> Deserialize<'de> for Value {
83 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
84 where
85 D: Deserializer<'de>,
86 {
87 struct ValueVisitor;
88
89 impl<'de> de::Visitor<'de> for ValueVisitor {
90 type Value = Value;
91
92 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
93 formatter.write_str("string containing a JSON number")
94 }
95
96 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
97 where
98 E: de::Error,
99 {
100 self.visit_string(v.to_owned())
101 }
102
103 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
104 where
105 E: de::Error,
106 {
107 match JsonNumberBuf::new(v) {
108 Ok(v) => Ok(Value(v)),
109 Err(e) => Err(de::Error::custom(e)),
110 }
111 }
112 }
113
114 deserializer.deserialize_identifier(ValueVisitor)
115 }
116 }
117
118 match map.next_key()? {
119 Some(Key) => {
120 let value: Value = map.next_value()?;
121 Ok(value.0)
122 }
123 None => Err(de::Error::invalid_type(de::Unexpected::Map, &self)),
124 }
125 }
126}
127
128#[derive(Debug)]
130pub struct Unexpected(String);
131
132impl fmt::Display for Unexpected {
133 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
134 self.0.fmt(f)
135 }
136}
137
138impl std::error::Error for Unexpected {}
139
140impl de::Error for Unexpected {
141 fn custom<T>(msg: T) -> Self
142 where
143 T: fmt::Display,
144 {
145 Self(msg.to_string())
146 }
147
148 fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
149 if let de::Unexpected::Unit = unexp {
150 Self::custom(format_args!("invalid type: null, expected {}", exp))
151 } else {
152 Self::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
153 }
154 }
155}
156
157impl<'de> Deserializer<'de> for JsonNumberBuf {
158 type Error = Unexpected;
159
160 #[inline(always)]
161 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
162 where
163 V: serde::de::Visitor<'de>,
164 {
165 self.as_number().deserialize_any(visitor)
166 }
167
168 forward_to_deserialize_any! {
169 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
170 bytes byte_buf option unit unit_struct seq tuple
171 tuple_struct map struct newtype_struct enum identifier ignored_any
172 }
173}
174
175impl<'de> Deserializer<'de> for &JsonNumberBuf {
176 type Error = Unexpected;
177
178 #[inline(always)]
179 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
180 where
181 V: serde::de::Visitor<'de>,
182 {
183 self.as_number().deserialize_any(visitor)
184 }
185
186 forward_to_deserialize_any! {
187 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
188 bytes byte_buf option unit unit_struct seq tuple
189 tuple_struct map struct newtype_struct enum identifier ignored_any
190 }
191}
192
193impl<'de> Deserializer<'de> for &JsonNumber {
194 type Error = Unexpected;
195
196 #[inline(always)]
197 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
198 where
199 V: serde::de::Visitor<'de>,
200 {
201 struct MapAccess<'n> {
207 data: Option<&'n JsonNumber>,
208 }
209
210 impl<'de, 'n> serde::de::MapAccess<'de> for MapAccess<'n> {
211 type Error = Unexpected;
212
213 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
214 where
215 K: de::DeserializeSeed<'de>,
216 {
217 if self.data.is_some() {
218 seed.deserialize(StrDeserializer::new(NUMBER_TOKEN))
219 .map(Some)
220 } else {
221 Ok(None)
222 }
223 }
224
225 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
226 where
227 V: de::DeserializeSeed<'de>,
228 {
229 match self.data.take() {
230 Some(data) => seed.deserialize(StrDeserializer::new(data.as_str())),
231 None => Err(Unexpected("value".to_owned())),
232 }
233 }
234 }
235
236 if let Some(u) = self.as_u64() {
237 visitor.visit_u64(u)
238 } else if let Some(i) = self.as_i64() {
239 visitor.visit_i64(i)
240 } else {
241 visitor.visit_map(MapAccess { data: Some(self) })
242 }
243 }
244
245 forward_to_deserialize_any! {
246 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
247 bytes byte_buf option unit unit_struct seq tuple
248 tuple_struct map struct newtype_struct enum identifier ignored_any
249 }
250}