1#![allow(clippy::items_after_test_module)]
4
5use crate::document::{DocumentError, DocumentResult, Value};
6use serde::{
7 Deserializer, Serialize,
8 de::{self, DeserializeOwned},
9 ser,
10};
11
12pub fn from_value<T: DeserializeOwned>(value: &Value, path: &str) -> DocumentResult<T> {
14 T::deserialize(ValueDeserializer(value)).map_err(|error| DocumentError::from_serde(path, error))
15}
16
17pub fn to_value<T: Serialize>(value: &T) -> DocumentResult<Value> {
19 value
20 .serialize(ValueSerializer)
21 .map_err(|error| DocumentError::ParseError {
22 format: "serde".to_string(),
23 detail: error.to_string(),
24 })
25}
26
27struct ValueSerializer;
28
29#[derive(Debug)]
30struct SerializeError(String);
31
32impl std::fmt::Display for SerializeError {
33 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 formatter.write_str(&self.0)
35 }
36}
37
38impl std::error::Error for SerializeError {}
39
40impl serde::ser::Error for SerializeError {
41 fn custom<T: std::fmt::Display>(message: T) -> Self {
42 Self(message.to_string())
43 }
44}
45
46type Result<T, E = SerializeError> = std::result::Result<T, E>;
47
48impl serde::Serializer for ValueSerializer {
49 type Ok = Value;
50 type Error = SerializeError;
51 type SerializeSeq = SequenceSerializer;
52 type SerializeTuple = SequenceSerializer;
53 type SerializeTupleStruct = SequenceSerializer;
54 type SerializeTupleVariant = VariantSequenceSerializer;
55 type SerializeMap = MapSerializer;
56 type SerializeStruct = MapSerializer;
57 type SerializeStructVariant = VariantMapSerializer;
58
59 fn serialize_bool(self, value: bool) -> Result<Value> {
60 Ok(Value::Bool(value))
61 }
62 fn serialize_i8(self, value: i8) -> Result<Value> {
63 Ok(Value::Integer(i64::from(value)))
64 }
65 fn serialize_i16(self, value: i16) -> Result<Value> {
66 Ok(Value::Integer(i64::from(value)))
67 }
68 fn serialize_i32(self, value: i32) -> Result<Value> {
69 Ok(Value::Integer(i64::from(value)))
70 }
71 fn serialize_i64(self, value: i64) -> Result<Value> {
72 Ok(Value::Integer(value))
73 }
74 fn serialize_u8(self, value: u8) -> Result<Value> {
75 Ok(Value::Unsigned(u64::from(value)))
76 }
77 fn serialize_u16(self, value: u16) -> Result<Value> {
78 Ok(Value::Unsigned(u64::from(value)))
79 }
80 fn serialize_u32(self, value: u32) -> Result<Value> {
81 Ok(Value::Unsigned(u64::from(value)))
82 }
83 fn serialize_u64(self, value: u64) -> Result<Value> {
84 Ok(Value::Unsigned(value))
85 }
86 fn serialize_f32(self, value: f32) -> Result<Value> {
87 self.serialize_f64(f64::from(value))
88 }
89 fn serialize_f64(self, value: f64) -> Result<Value> {
90 if value.is_finite() {
91 Ok(Value::Float(value))
92 } else {
93 Err(SerializeError(
94 "non-finite float is not a document value".to_string(),
95 ))
96 }
97 }
98 fn serialize_char(self, value: char) -> Result<Value> {
99 Ok(Value::String(value.to_string()))
100 }
101 fn serialize_str(self, value: &str) -> Result<Value> {
102 Ok(Value::String(value.to_string()))
103 }
104 fn serialize_bytes(self, _value: &[u8]) -> Result<Value> {
105 Err(SerializeError(
106 "bytes require an explicit string or sequence representation".to_string(),
107 ))
108 }
109 fn serialize_none(self) -> Result<Value> {
110 Ok(Value::Null)
111 }
112 fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Value> {
113 value.serialize(self)
114 }
115 fn serialize_unit(self) -> Result<Value> {
116 Ok(Value::Null)
117 }
118 fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
119 Ok(Value::Null)
120 }
121 fn serialize_unit_variant(
122 self,
123 _name: &'static str,
124 _index: u32,
125 variant: &'static str,
126 ) -> Result<Value> {
127 Ok(Value::String(variant.to_string()))
128 }
129 fn serialize_newtype_struct<T: ?Sized + Serialize>(
130 self,
131 _name: &'static str,
132 value: &T,
133 ) -> Result<Value> {
134 value.serialize(self)
135 }
136 fn serialize_newtype_variant<T: ?Sized + Serialize>(
137 self,
138 _name: &'static str,
139 _index: u32,
140 variant: &'static str,
141 value: &T,
142 ) -> Result<Value> {
143 let mut map = BTreeMap::new();
144 map.insert(variant.to_string(), value.serialize(ValueSerializer)?);
145 Ok(Value::Object(map))
146 }
147 fn serialize_seq(self, len: Option<usize>) -> Result<SequenceSerializer> {
148 Ok(SequenceSerializer {
149 values: Vec::with_capacity(len.unwrap_or(0)),
150 })
151 }
152 fn serialize_tuple(self, len: usize) -> Result<SequenceSerializer> {
153 self.serialize_seq(Some(len))
154 }
155 fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SequenceSerializer> {
156 self.serialize_seq(Some(len))
157 }
158 fn serialize_tuple_variant(
159 self,
160 _name: &'static str,
161 _index: u32,
162 variant: &'static str,
163 len: usize,
164 ) -> Result<VariantSequenceSerializer> {
165 Ok(VariantSequenceSerializer {
166 variant: variant.to_string(),
167 values: Vec::with_capacity(len),
168 })
169 }
170 fn serialize_map(self, _len: Option<usize>) -> Result<MapSerializer> {
171 Ok(MapSerializer {
172 values: BTreeMap::new(),
173 next_key: None,
174 })
175 }
176 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<MapSerializer> {
177 self.serialize_map(Some(len))
178 }
179 fn serialize_struct_variant(
180 self,
181 _name: &'static str,
182 _index: u32,
183 variant: &'static str,
184 _len: usize,
185 ) -> Result<VariantMapSerializer> {
186 Ok(VariantMapSerializer {
187 variant: variant.to_string(),
188 map: MapSerializer {
189 values: BTreeMap::new(),
190 next_key: None,
191 },
192 })
193 }
194}
195
196use serde::ser::{
197 SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
198 SerializeTupleStruct, SerializeTupleVariant,
199};
200use std::collections::BTreeMap;
201
202struct SequenceSerializer {
203 values: Vec<Value>,
204}
205impl SerializeSeq for SequenceSerializer {
206 type Ok = Value;
207 type Error = SerializeError;
208 fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
209 self.values.push(value.serialize(ValueSerializer)?);
210 Ok(())
211 }
212 fn end(self) -> Result<Value> {
213 Ok(Value::Array(self.values))
214 }
215}
216impl SerializeTuple for SequenceSerializer {
217 type Ok = Value;
218 type Error = SerializeError;
219 fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
220 self.values.push(value.serialize(ValueSerializer)?);
221 Ok(())
222 }
223 fn end(self) -> Result<Value> {
224 Ok(Value::Array(self.values))
225 }
226}
227impl SerializeTupleStruct for SequenceSerializer {
228 type Ok = Value;
229 type Error = SerializeError;
230 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
231 self.values.push(value.serialize(ValueSerializer)?);
232 Ok(())
233 }
234 fn end(self) -> Result<Value> {
235 Ok(Value::Array(self.values))
236 }
237}
238
239struct VariantSequenceSerializer {
240 variant: String,
241 values: Vec<Value>,
242}
243impl SerializeTupleVariant for VariantSequenceSerializer {
244 type Ok = Value;
245 type Error = SerializeError;
246 fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
247 self.values.push(value.serialize(ValueSerializer)?);
248 Ok(())
249 }
250 fn end(self) -> Result<Value> {
251 let mut map = BTreeMap::new();
252 map.insert(self.variant, Value::Array(self.values));
253 Ok(Value::Object(map))
254 }
255}
256
257struct MapSerializer {
258 values: BTreeMap<String, Value>,
259 next_key: Option<String>,
260}
261impl SerializeMap for MapSerializer {
262 type Ok = Value;
263 type Error = SerializeError;
264 fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<()> {
265 let Value::String(key) = key.serialize(ValueKeySerializer)? else {
266 return Err(SerializeError("map keys must be strings".to_string()));
267 };
268 self.next_key = Some(key);
269 Ok(())
270 }
271 fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<()> {
272 let key = self
273 .next_key
274 .take()
275 .ok_or_else(|| SerializeError("map value without key".to_string()))?;
276 self.values.insert(key, value.serialize(ValueSerializer)?);
277 Ok(())
278 }
279 fn end(self) -> Result<Value> {
280 Ok(Value::Object(self.values))
281 }
282}
283impl SerializeStruct for MapSerializer {
284 type Ok = Value;
285 type Error = SerializeError;
286 fn serialize_field<T: ?Sized + Serialize>(
287 &mut self,
288 key: &'static str,
289 value: &T,
290 ) -> Result<()> {
291 self.values
292 .insert(key.to_string(), value.serialize(ValueSerializer)?);
293 Ok(())
294 }
295 fn end(self) -> Result<Value> {
296 Ok(Value::Object(self.values))
297 }
298}
299
300struct VariantMapSerializer {
301 variant: String,
302 map: MapSerializer,
303}
304impl SerializeStructVariant for VariantMapSerializer {
305 type Ok = Value;
306 type Error = SerializeError;
307 fn serialize_field<T: ?Sized + Serialize>(
308 &mut self,
309 key: &'static str,
310 value: &T,
311 ) -> Result<()> {
312 self.map.serialize_field(key, value)
313 }
314 fn end(self) -> Result<Value> {
315 let mut outer = BTreeMap::new();
316 outer.insert(self.variant, Value::Object(self.map.values));
317 Ok(Value::Object(outer))
318 }
319}
320
321struct ValueKeySerializer;
322impl serde::Serializer for ValueKeySerializer {
323 type Ok = Value;
324 type Error = SerializeError;
325 type SerializeSeq = ser::Impossible<Value, SerializeError>;
326 type SerializeTuple = ser::Impossible<Value, SerializeError>;
327 type SerializeTupleStruct = ser::Impossible<Value, SerializeError>;
328 type SerializeTupleVariant = ser::Impossible<Value, SerializeError>;
329 type SerializeMap = ser::Impossible<Value, SerializeError>;
330 type SerializeStruct = ser::Impossible<Value, SerializeError>;
331 type SerializeStructVariant = ser::Impossible<Value, SerializeError>;
332 fn serialize_str(self, value: &str) -> Result<Value> {
333 Ok(Value::String(value.to_string()))
334 }
335 fn serialize_bool(self, _: bool) -> Result<Value> {
336 Err(SerializeError("map keys must be strings".to_string()))
337 }
338 fn serialize_i8(self, _: i8) -> Result<Value> {
339 Err(SerializeError("map keys must be strings".to_string()))
340 }
341 fn serialize_i16(self, _: i16) -> Result<Value> {
342 Err(SerializeError("map keys must be strings".to_string()))
343 }
344 fn serialize_i32(self, _: i32) -> Result<Value> {
345 Err(SerializeError("map keys must be strings".to_string()))
346 }
347 fn serialize_i64(self, _: i64) -> Result<Value> {
348 Err(SerializeError("map keys must be strings".to_string()))
349 }
350 fn serialize_u8(self, _: u8) -> Result<Value> {
351 Err(SerializeError("map keys must be strings".to_string()))
352 }
353 fn serialize_u16(self, _: u16) -> Result<Value> {
354 Err(SerializeError("map keys must be strings".to_string()))
355 }
356 fn serialize_u32(self, _: u32) -> Result<Value> {
357 Err(SerializeError("map keys must be strings".to_string()))
358 }
359 fn serialize_u64(self, _: u64) -> Result<Value> {
360 Err(SerializeError("map keys must be strings".to_string()))
361 }
362 fn serialize_f32(self, _: f32) -> Result<Value> {
363 Err(SerializeError("map keys must be strings".to_string()))
364 }
365 fn serialize_f64(self, _: f64) -> Result<Value> {
366 Err(SerializeError("map keys must be strings".to_string()))
367 }
368 fn serialize_char(self, _: char) -> Result<Value> {
369 Err(SerializeError("map keys must be strings".to_string()))
370 }
371 fn serialize_bytes(self, _: &[u8]) -> Result<Value> {
372 Err(SerializeError("map keys must be strings".to_string()))
373 }
374 fn serialize_none(self) -> Result<Value> {
375 Err(SerializeError("map keys must be strings".to_string()))
376 }
377 fn serialize_some<T: ?Sized + Serialize>(self, _: &T) -> Result<Value> {
378 Err(SerializeError("map keys must be strings".to_string()))
379 }
380 fn serialize_unit(self) -> Result<Value> {
381 Err(SerializeError("map keys must be strings".to_string()))
382 }
383 fn serialize_unit_struct(self, _: &'static str) -> Result<Value> {
384 Err(SerializeError("map keys must be strings".to_string()))
385 }
386 fn serialize_unit_variant(self, _: &'static str, _: u32, _: &'static str) -> Result<Value> {
387 Err(SerializeError("map keys must be strings".to_string()))
388 }
389 fn serialize_newtype_struct<T: ?Sized + Serialize>(
390 self,
391 _: &'static str,
392 _: &T,
393 ) -> Result<Value> {
394 Err(SerializeError("map keys must be strings".to_string()))
395 }
396 fn serialize_newtype_variant<T: ?Sized + Serialize>(
397 self,
398 _: &'static str,
399 _: u32,
400 _: &'static str,
401 _: &T,
402 ) -> Result<Value> {
403 Err(SerializeError("map keys must be strings".to_string()))
404 }
405 fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
406 Err(SerializeError("map keys must be strings".to_string()))
407 }
408 fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
409 Err(SerializeError("map keys must be strings".to_string()))
410 }
411 fn serialize_tuple_struct(
412 self,
413 _: &'static str,
414 _: usize,
415 ) -> Result<Self::SerializeTupleStruct> {
416 Err(SerializeError("map keys must be strings".to_string()))
417 }
418 fn serialize_tuple_variant(
419 self,
420 _: &'static str,
421 _: u32,
422 _: &'static str,
423 _: usize,
424 ) -> Result<Self::SerializeTupleVariant> {
425 Err(SerializeError("map keys must be strings".to_string()))
426 }
427 fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap> {
428 Err(SerializeError("map keys must be strings".to_string()))
429 }
430 fn serialize_struct(self, _: &'static str, _: usize) -> Result<Self::SerializeStruct> {
431 Err(SerializeError("map keys must be strings".to_string()))
432 }
433 fn serialize_struct_variant(
434 self,
435 _: &'static str,
436 _: u32,
437 _: &'static str,
438 _: usize,
439 ) -> Result<Self::SerializeStructVariant> {
440 Err(SerializeError("map keys must be strings".to_string()))
441 }
442}
443
444fn visit_number_literal<'de, V: de::Visitor<'de>>(
447 text: &str,
448 visitor: V,
449) -> Result<V::Value, serde::de::value::Error> {
450 if let Ok(value) = text.parse::<i64>() {
451 return visitor.visit_i64(value);
452 }
453 if let Ok(value) = text.parse::<u64>() {
454 return visitor.visit_u64(value);
455 }
456 match text.parse::<f64>() {
457 Ok(value) => visitor.visit_f64(value),
458 Err(_) => Err(de::Error::custom(format!(
459 "invalid numeric literal `{text}`"
460 ))),
461 }
462}
463
464struct ValueDeserializer<'a>(&'a Value);
465
466macro_rules! string_number {
467 ($method:ident, $type:ty, $visit:ident) => {
468 fn $method<V: serde::de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
469 match self.0 {
470 Value::String(value) => value
471 .parse::<$type>()
472 .map_err(|_| de::Error::custom("invalid numeric string"))
473 .and_then(|value| visitor.$visit(value)),
474 _ => self.deserialize_any(visitor),
475 }
476 }
477 };
478}
479
480impl<'de, 'a> serde::Deserializer<'de> for ValueDeserializer<'a>
481where
482 'a: 'de,
483{
484 type Error = serde::de::value::Error;
485
486 fn deserialize_any<V: serde::de::Visitor<'de>>(
487 self,
488 visitor: V,
489 ) -> Result<V::Value, Self::Error> {
490 match self.0 {
491 Value::Null => visitor.visit_unit(),
492 Value::Bool(value) => visitor.visit_bool(*value),
493 Value::Integer(value) => visitor.visit_i64(*value),
494 Value::Unsigned(value) => visitor.visit_u64(*value),
495 Value::Float(value) => visitor.visit_f64(*value),
496 Value::Number(text) => visit_number_literal(text, visitor),
505 Value::String(value) => visitor.visit_string(value.clone()),
506 Value::Array(values) => visitor.visit_seq(BorrowedSeqAccess {
507 values: values.iter(),
508 }),
509 Value::Object(values) => visitor.visit_map(BorrowedMapAccess {
510 values: values.iter(),
511 pending: None,
512 }),
513 }
514 }
515
516 fn deserialize_option<V: serde::de::Visitor<'de>>(
517 self,
518 visitor: V,
519 ) -> Result<V::Value, Self::Error> {
520 if self.0.is_null() {
521 visitor.visit_none()
522 } else {
523 visitor.visit_some(self)
524 }
525 }
526
527 fn deserialize_enum<V: serde::de::Visitor<'de>>(
528 self,
529 _name: &'static str,
530 _variants: &'static [&'static str],
531 visitor: V,
532 ) -> Result<V::Value, Self::Error> {
533 match self.0 {
534 Value::String(variant) => visitor.visit_enum(EnumAccess {
535 variant: variant.clone(),
536 value: None,
537 }),
538 Value::Object(values) if values.len() == 1 => {
539 let mut entries = values.iter();
540 if let Some((variant, value)) = entries.next() {
541 visitor.visit_enum(EnumAccess {
542 variant: variant.clone(),
543 value: Some(value),
544 })
545 } else {
546 Err(de::Error::custom("missing enum variant"))
547 }
548 }
549 _ => Err(de::Error::custom(
550 "expected enum variant string or single-key object",
551 )),
552 }
553 }
554
555 fn deserialize_bool<V: serde::de::Visitor<'de>>(
556 self,
557 visitor: V,
558 ) -> Result<V::Value, Self::Error> {
559 match self.0 {
560 Value::String(value) => match value.to_ascii_lowercase().as_str() {
561 "true" | "yes" | "on" | "1" => visitor.visit_bool(true),
562 "false" | "no" | "off" | "0" => visitor.visit_bool(false),
563 _ => Err(de::Error::custom("invalid boolean string")),
564 },
565 _ => self.deserialize_any(visitor),
566 }
567 }
568
569 string_number!(deserialize_i8, i8, visit_i8);
570 string_number!(deserialize_i16, i16, visit_i16);
571 string_number!(deserialize_i32, i32, visit_i32);
572 string_number!(deserialize_i64, i64, visit_i64);
573 string_number!(deserialize_i128, i128, visit_i128);
574 string_number!(deserialize_u8, u8, visit_u8);
575 string_number!(deserialize_u16, u16, visit_u16);
576 string_number!(deserialize_u32, u32, visit_u32);
577 string_number!(deserialize_u64, u64, visit_u64);
578 string_number!(deserialize_u128, u128, visit_u128);
579 string_number!(deserialize_f32, f32, visit_f32);
580 string_number!(deserialize_f64, f64, visit_f64);
581
582 serde::forward_to_deserialize_any! {
583 char str string bytes byte_buf
584 unit unit_struct newtype_struct seq tuple tuple_struct map struct identifier ignored_any
585 }
586}
587
588struct BorrowedSeqAccess<'a> {
589 values: std::slice::Iter<'a, Value>,
590}
591
592impl<'de, 'a> serde::de::SeqAccess<'de> for BorrowedSeqAccess<'a>
593where
594 'a: 'de,
595{
596 type Error = serde::de::value::Error;
597 fn next_element_seed<T: serde::de::DeserializeSeed<'de>>(
598 &mut self,
599 seed: T,
600 ) -> Result<Option<T::Value>, Self::Error> {
601 self.values
602 .next()
603 .map(|value| seed.deserialize(ValueDeserializer(value)))
604 .transpose()
605 }
606}
607
608struct BorrowedMapAccess<'a> {
609 values: std::collections::btree_map::Iter<'a, String, Value>,
610 pending: Option<&'a Value>,
611}
612
613impl<'de, 'a> serde::de::MapAccess<'de> for BorrowedMapAccess<'a>
614where
615 'a: 'de,
616{
617 type Error = serde::de::value::Error;
618 fn next_key_seed<K: serde::de::DeserializeSeed<'de>>(
619 &mut self,
620 seed: K,
621 ) -> Result<Option<K::Value>, Self::Error> {
622 match self.values.next() {
623 Some((key, value)) => {
624 self.pending = Some(value);
625 seed.deserialize(serde::de::IntoDeserializer::into_deserializer(key.clone()))
626 .map(Some)
627 }
628 None => Ok(None),
629 }
630 }
631 fn next_value_seed<V: serde::de::DeserializeSeed<'de>>(
632 &mut self,
633 seed: V,
634 ) -> Result<V::Value, Self::Error> {
635 let value = self
636 .pending
637 .take()
638 .ok_or_else(|| de::Error::custom("map value without key"))?;
639 seed.deserialize(ValueDeserializer(value))
640 }
641}
642
643struct EnumAccess<'a> {
644 variant: String,
645 value: Option<&'a Value>,
646}
647
648impl<'de, 'a> serde::de::EnumAccess<'de> for EnumAccess<'a>
649where
650 'a: 'de,
651{
652 type Error = serde::de::value::Error;
653 type Variant = VariantAccess<'a>;
654 fn variant_seed<V: serde::de::DeserializeSeed<'de>>(
655 self,
656 seed: V,
657 ) -> Result<(V::Value, Self::Variant), Self::Error> {
658 let variant =
659 seed.deserialize(serde::de::IntoDeserializer::into_deserializer(self.variant))?;
660 Ok((variant, VariantAccess { value: self.value }))
661 }
662}
663
664struct VariantAccess<'a> {
665 value: Option<&'a Value>,
666}
667
668#[cfg(test)]
669mod tests {
670 use super::{from_value, to_value};
671 use crate::document::Value;
672 use serde::{Deserialize, Serialize};
673
674 #[derive(Debug, PartialEq, Serialize, Deserialize)]
675 struct Config {
676 name: String,
677 enabled: Option<bool>,
678 #[serde(flatten)]
679 extra: Extra,
680 }
681
682 #[derive(Debug, PartialEq, Serialize, Deserialize)]
683 struct Extra {
684 count: u64,
685 }
686
687 #[derive(Debug, PartialEq, Serialize, Deserialize)]
688 enum Mode {
689 Fast,
690 Custom { level: u32 },
691 }
692
693 #[test]
694 fn round_trips_struct_optional_flatten_and_enum() {
695 let value = Value::Object(std::collections::BTreeMap::from([
696 ("name".to_string(), Value::String("demo".to_string())),
697 ("enabled".to_string(), Value::Null),
698 ("count".to_string(), Value::Unsigned(9)),
699 ]));
700 let config: Config = from_value(&value, "root").unwrap_or_else(|error| panic!("{error}"));
701 assert_eq!(config.name, "demo");
702 assert_eq!(config.enabled, None);
703 assert_eq!(config.extra.count, 9);
704 let mode = Mode::Custom { level: 3 };
705 assert_eq!(
706 from_value(&to_value(&mode).unwrap_or(Value::Null), "mode").unwrap_or(Mode::Fast),
707 mode
708 );
709 }
710
711 #[derive(Debug, Deserialize)]
712 #[serde(deny_unknown_fields)]
713 struct Strict {
714 #[allow(dead_code)]
715 name: String,
716 }
717
718 #[test]
719 fn reports_typed_path_and_unknown_field() {
720 let value = Value::Object(std::collections::BTreeMap::from([
721 ("name".to_string(), Value::String("demo".to_string())),
722 ("extra".to_string(), Value::Bool(true)),
723 ]));
724 let error = from_value::<Strict>(&value, "settings").expect_err("unknown field must fail");
725 assert!(error.to_string().contains("settings"));
726 assert!(error.to_string().contains("unknown field"));
727 }
728
729 #[test]
730 fn directs_string_leaves_into_typed_scalars() {
731 let value = Value::Object(std::collections::BTreeMap::from([
732 ("enabled".to_string(), Value::String("yes".to_string())),
733 ("count".to_string(), Value::String("42".to_string())),
734 ]));
735 #[derive(Debug, Deserialize, PartialEq)]
736 struct StringBacked {
737 enabled: bool,
738 count: u64,
739 }
740 assert_eq!(
741 from_value::<StringBacked>(&value, "env").unwrap_or_else(|error| panic!("{error}")),
742 StringBacked {
743 enabled: true,
744 count: 42
745 }
746 );
747 }
748}
749impl<'de, 'a> serde::de::VariantAccess<'de> for VariantAccess<'a>
750where
751 'a: 'de,
752{
753 type Error = serde::de::value::Error;
754 fn unit_variant(self) -> Result<(), Self::Error> {
755 if self.value.is_none() {
756 Ok(())
757 } else {
758 Err(de::Error::custom("expected unit variant"))
759 }
760 }
761 fn newtype_variant_seed<T: serde::de::DeserializeSeed<'de>>(
762 self,
763 seed: T,
764 ) -> Result<T::Value, Self::Error> {
765 seed.deserialize(ValueDeserializer(
766 self.value
767 .ok_or_else(|| de::Error::custom("missing newtype value"))?,
768 ))
769 }
770 fn tuple_variant<V: serde::de::Visitor<'de>>(
771 self,
772 _len: usize,
773 visitor: V,
774 ) -> Result<V::Value, Self::Error> {
775 ValueDeserializer(
776 self.value
777 .ok_or_else(|| de::Error::custom("missing tuple value"))?,
778 )
779 .deserialize_seq(visitor)
780 }
781 fn struct_variant<V: serde::de::Visitor<'de>>(
782 self,
783 _fields: &'static [&'static str],
784 visitor: V,
785 ) -> Result<V::Value, Self::Error> {
786 ValueDeserializer(
787 self.value
788 .ok_or_else(|| de::Error::custom("missing struct value"))?,
789 )
790 .deserialize_map(visitor)
791 }
792}