1use std::sync::Arc;
4
5use serde::{
6 Deserialize, Deserializer,
7 de::{
8 self, DeserializeSeed, Error as DeError, IntoDeserializer,
9 value::{MapDeserializer, SeqDeserializer},
10 },
11};
12
13use crate::{
14 error::ErrorWithOrigin,
15 utils::EnumVariant,
16 value::{Map, StrValue, Value, ValueOrigin, WithOrigin},
17};
18
19#[derive(Debug, Clone, Default)]
21pub struct DeserializerOptions {
22 pub coerce_variant_names: bool,
24}
25
26impl WithOrigin {
27 #[cold]
28 pub(super) fn invalid_type(&self, expected: &str) -> ErrorWithOrigin {
29 let actual = match &self.inner {
30 Value::Null => de::Unexpected::Unit,
31 Value::Bool(value) => de::Unexpected::Bool(*value),
32 Value::Number(value) => {
33 if let Some(value) = value.as_u64() {
34 de::Unexpected::Unsigned(value)
35 } else if let Some(value) = value.as_i64() {
36 de::Unexpected::Signed(value)
37 } else if let Some(value) = value.as_f64() {
38 de::Unexpected::Float(value)
39 } else {
40 de::Unexpected::Other("number")
41 }
42 }
43 Value::String(StrValue::Plain(s)) => de::Unexpected::Str(s),
44 Value::String(StrValue::Secret(_)) => de::Unexpected::Other("secret"),
45 Value::Array(_) => de::Unexpected::Seq,
46 Value::Object(_) => de::Unexpected::Map,
47 };
48 ErrorWithOrigin::json(
49 DeError::invalid_type(actual, &expected),
50 self.origin.clone(),
51 )
52 }
53}
54
55macro_rules! parse_int_value {
56 ($($ty:ident => $method:ident,)*) => {
57 $(
58 fn $method<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
59 let result = match self.value() {
60 Value::String(s) => {
61 match s.expose().parse::<$ty>() {
62 Ok(val) => val.into_deserializer().$method(visitor),
63 Err(err) => {
64 let err = DeError::custom(format_args!("{err} while parsing {} value '{s}'", stringify!($ty)));
65 return Err(self.enrich_err(err));
66 }
67 }
68 }
69 Value::Number(number) => number.deserialize_any(visitor).map_err(|err| self.enrich_err(err.into())),
70 _ => return Err(self.invalid_type(&format!("{} number", stringify!($ty)))),
71 };
72 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
73 }
74 )*
75 }
76}
77
78#[derive(Debug, Clone, Copy)]
79pub struct ValueDeserializer<'a> {
80 value: &'a WithOrigin,
81 options: &'a DeserializerOptions,
82}
83
84impl<'a> ValueDeserializer<'a> {
85 pub(super) fn new(value: &'a WithOrigin, options: &'a DeserializerOptions) -> Self {
86 Self { value, options }
87 }
88
89 pub(super) fn value(&self) -> &'a Value {
90 &self.value.inner
91 }
92
93 pub(super) fn origin(&self) -> &Arc<ValueOrigin> {
94 &self.value.origin
95 }
96
97 pub(super) fn enrich_err(&self, err: serde_json::Error) -> ErrorWithOrigin {
98 ErrorWithOrigin::json(err, self.value.origin.clone())
99 }
100
101 pub(super) fn invalid_type(&self, expected: &str) -> ErrorWithOrigin {
102 self.value.invalid_type(expected)
103 }
104
105 fn parse_array<'de, V: de::Visitor<'de>>(
106 &self,
107 array: &[WithOrigin],
108 visitor: V,
109 ) -> Result<V::Value, ErrorWithOrigin> {
110 let mut deserializer = SeqDeserializer::new(
111 array
112 .iter()
113 .map(|val| ValueDeserializer::new(val, self.options)),
114 );
115 let seq = visitor.visit_seq(&mut deserializer)?;
116 deserializer.end()?;
117 Ok(seq)
118 }
119
120 fn parse_object<'de, V: de::Visitor<'de>>(
121 &self,
122 object: &Map,
123 visitor: V,
124 ) -> Result<V::Value, ErrorWithOrigin> {
125 let mut deserializer = MapDeserializer::new(
126 object
127 .iter()
128 .map(|(key, value)| (key.as_str(), ValueDeserializer::new(value, self.options))),
129 );
130 let map = visitor.visit_map(&mut deserializer)?;
131 deserializer.end()?;
132 Ok(map)
133 }
134}
135
136impl<'de> Deserializer<'de> for ValueDeserializer<'_> {
137 type Error = ErrorWithOrigin;
138
139 fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
140 let result = match self.value() {
141 Value::Null => visitor.visit_none(),
142 Value::Bool(value) => visitor.visit_bool(*value),
143 Value::Number(value) => value
144 .deserialize_any(visitor)
145 .map_err(|err| self.enrich_err(err)),
146 Value::String(value) => visitor.visit_str(value.expose()),
147 Value::Array(array) => self.parse_array(array, visitor),
148 Value::Object(object) => self.parse_object(object, visitor),
149 };
150 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
151 }
152
153 fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
154 let result = match self.value() {
155 Value::Null => visitor.visit_none(),
156 _ => visitor.visit_some(self),
157 };
158 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
159 }
160
161 fn deserialize_newtype_struct<V: de::Visitor<'de>>(
162 self,
163 _name: &'static str,
164 visitor: V,
165 ) -> Result<V::Value, Self::Error> {
166 visitor
167 .visit_newtype_struct(self)
168 .map_err(|err| err.set_origin_if_unset(&self.value.origin))
169 }
170
171 fn deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
172 let result = match self.value() {
173 Value::Array(array) => self.parse_array(array, visitor),
174 _ => Err(self.invalid_type("array")),
175 };
176 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
177 }
178
179 fn deserialize_tuple<V: de::Visitor<'de>>(
180 self,
181 _len: usize,
182 visitor: V,
183 ) -> Result<V::Value, Self::Error> {
184 self.deserialize_seq(visitor)
185 .map_err(|err| err.set_origin_if_unset(&self.value.origin))
186 }
187
188 fn deserialize_tuple_struct<V: de::Visitor<'de>>(
189 self,
190 _name: &'static str,
191 _len: usize,
192 visitor: V,
193 ) -> Result<V::Value, Self::Error> {
194 self.deserialize_seq(visitor)
195 .map_err(|err| err.set_origin_if_unset(&self.value.origin))
196 }
197
198 fn deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
199 let result = match self.value() {
200 Value::Object(object) => self.parse_object(object, visitor),
201 _ => Err(self.invalid_type("object")),
202 };
203 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
204 }
205
206 fn deserialize_struct<V: de::Visitor<'de>>(
207 self,
208 _name: &'static str,
209 _fields: &'static [&'static str],
210 visitor: V,
211 ) -> Result<V::Value, Self::Error> {
212 let result = match self.value() {
213 Value::Array(array) => self.parse_array(array, visitor),
214 Value::Object(object) => self.parse_object(object, visitor),
215 _ => Err(self.invalid_type("array or object")),
216 };
217 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
218 }
219
220 fn deserialize_enum<V: de::Visitor<'de>>(
221 self,
222 _name: &'static str,
223 variants: &'static [&'static str],
224 visitor: V,
225 ) -> Result<V::Value, Self::Error> {
226 let (mut variant, value) = match self.value() {
227 Value::Object(object) if object.len() == 1 => {
228 let (variant, value) = object.iter().next().unwrap();
229 (variant.as_str(), Some(value))
230 }
231 Value::String(s) => (s.expose(), None),
232 _ => return Err(self.invalid_type("string or object with single key")),
233 };
234
235 if self.options.coerce_variant_names {
236 if let Some(parsed) = EnumVariant::new(variant) {
237 if let Some(expected_variant) = parsed.try_match(variants) {
238 variant = expected_variant;
239 }
240 }
241 }
242
243 visitor
244 .visit_enum(EnumDeserializer {
245 variant,
246 inner: VariantDeserializer {
247 value,
248 options: self.options,
249 parent_origin: self.value.origin.clone(),
250 },
251 })
252 .map_err(|err| err.set_origin_if_unset(&self.value.origin))
253 }
254
255 fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
258 let result = match self.value() {
259 Value::Bool(value) => visitor.visit_bool(*value),
260 Value::String(s) => match s.expose().parse::<bool>() {
261 Ok(val) => visitor.visit_bool(val),
262 Err(err) => {
263 let err =
264 DeError::custom(format_args!("{err} while parsing value '{s}' as boolean"));
265 return Err(self.enrich_err(err));
266 }
267 },
268 _ => return Err(self.invalid_type("boolean or boolean-like string")),
269 };
270 result.map_err(|err: serde_json::Error| self.enrich_err(err))
271 }
272
273 parse_int_value! {
274 u8 => deserialize_u8,
275 u16 => deserialize_u16,
276 u32 => deserialize_u32,
277 u64 => deserialize_u64,
278 i8 => deserialize_i8,
279 i16 => deserialize_i16,
280 i32 => deserialize_i32,
281 i64 => deserialize_i64,
282 u128 => deserialize_u128,
283 i128 => deserialize_i128,
284 f32 => deserialize_f32,
285 f64 => deserialize_f64,
286 }
287
288 fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
289 let result = match self.value() {
290 Value::String(s) => visitor.visit_str(s.expose()),
291 Value::Null => visitor.visit_string("null".to_string()),
292 Value::Bool(value) => visitor.visit_string(value.to_string()),
293 Value::Number(value) => visitor.visit_string(value.to_string()),
294 _ => Err(self.invalid_type("string or other primitive type")),
295 };
296 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
297 }
298
299 fn deserialize_char<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
300 self.deserialize_string(visitor)
301 }
302
303 fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
304 self.deserialize_string(visitor)
305 }
306
307 fn deserialize_byte_buf<V: de::Visitor<'de>>(
308 self,
309 visitor: V,
310 ) -> Result<V::Value, Self::Error> {
311 let result = match self.value() {
312 Value::String(s) => visitor.visit_str(s.expose()),
313 Value::Array(array) => self.parse_array(array, visitor),
314 _ => return Err(self.invalid_type("string or array")),
315 };
316 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
317 }
318
319 fn deserialize_bytes<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
320 self.deserialize_byte_buf(visitor)
321 }
322
323 fn deserialize_identifier<V: de::Visitor<'de>>(
324 self,
325 visitor: V,
326 ) -> Result<V::Value, Self::Error> {
327 self.deserialize_string(visitor)
328 }
329
330 fn deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
331 let result = match self.value() {
332 Value::Null => visitor.visit_unit(),
333 _ => Err(self.invalid_type("null")),
334 };
335 result.map_err(|err| err.set_origin_if_unset(&self.value.origin))
336 }
337
338 fn deserialize_unit_struct<V: de::Visitor<'de>>(
339 self,
340 _name: &'static str,
341 visitor: V,
342 ) -> Result<V::Value, Self::Error> {
343 self.deserialize_unit(visitor)
344 }
345
346 fn deserialize_ignored_any<V: de::Visitor<'de>>(
347 self,
348 visitor: V,
349 ) -> Result<V::Value, Self::Error> {
350 visitor
351 .visit_unit()
352 .map_err(|err: serde_json::Error| self.enrich_err(err))
353 }
354}
355
356impl IntoDeserializer<'_, ErrorWithOrigin> for ValueDeserializer<'_> {
357 type Deserializer = Self;
358
359 fn into_deserializer(self) -> Self::Deserializer {
360 self
361 }
362}
363
364#[derive(Debug)]
365struct EnumDeserializer<'a> {
366 variant: &'a str,
367 inner: VariantDeserializer<'a>,
368}
369
370impl<'a, 'de> de::EnumAccess<'de> for EnumDeserializer<'a> {
371 type Error = ErrorWithOrigin;
372 type Variant = VariantDeserializer<'a>;
373
374 fn variant_seed<V: DeserializeSeed<'de>>(
375 self,
376 seed: V,
377 ) -> Result<(V::Value, Self::Variant), Self::Error> {
378 let variant = self.variant.into_deserializer();
379 match seed.deserialize(variant) {
380 Ok(val) => Ok((val, self.inner)),
381 Err(err) => Err(ErrorWithOrigin::json(err, self.inner.origin().clone())),
382 }
383 }
384}
385
386#[derive(Debug)]
387struct VariantDeserializer<'a> {
388 value: Option<&'a WithOrigin>,
389 options: &'a DeserializerOptions,
390 parent_origin: Arc<ValueOrigin>,
391}
392
393impl VariantDeserializer<'_> {
394 fn origin(&self) -> &Arc<ValueOrigin> {
395 self.value.map_or(&self.parent_origin, |val| &val.origin)
396 }
397}
398
399impl<'de> de::VariantAccess<'de> for VariantDeserializer<'_> {
400 type Error = ErrorWithOrigin;
401
402 fn unit_variant(self) -> Result<(), Self::Error> {
403 if let Some(value) = self.value {
404 Deserialize::deserialize(ValueDeserializer::new(value, self.options))
405 } else {
406 Ok(())
407 }
408 }
409
410 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
411 where
412 T: DeserializeSeed<'de>,
413 {
414 if let Some(value) = self.value {
415 seed.deserialize(ValueDeserializer::new(value, self.options))
416 } else {
417 let err = DeError::invalid_type(de::Unexpected::Unit, &"newtype variant");
418 Err(ErrorWithOrigin::json(err, self.parent_origin))
419 }
420 }
421
422 fn tuple_variant<V: de::Visitor<'de>>(
423 self,
424 _len: usize,
425 visitor: V,
426 ) -> Result<V::Value, Self::Error> {
427 if let Some(value) = self.value {
428 de::Deserializer::deserialize_seq(ValueDeserializer::new(value, self.options), visitor)
429 } else {
430 let err = DeError::invalid_type(de::Unexpected::Unit, &"tuple variant");
431 Err(ErrorWithOrigin::json(err, self.parent_origin))
432 }
433 }
434
435 fn struct_variant<V: de::Visitor<'de>>(
436 self,
437 _fields: &'static [&'static str],
438 visitor: V,
439 ) -> Result<V::Value, Self::Error> {
440 if let Some(value) = self.value {
441 de::Deserializer::deserialize_map(ValueDeserializer::new(value, self.options), visitor)
442 } else {
443 let err = DeError::invalid_type(de::Unexpected::Unit, &"struct variant");
444 Err(ErrorWithOrigin::json(err, self.parent_origin))
445 }
446 }
447}