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 configuration 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
444struct ValueDeserializer<'a>(&'a Value);
445
446macro_rules! string_number {
447 ($method:ident, $type:ty, $visit:ident) => {
448 fn $method<V: serde::de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
449 match self.0 {
450 Value::String(value) => value
451 .parse::<$type>()
452 .map_err(|_| de::Error::custom("invalid numeric string"))
453 .and_then(|value| visitor.$visit(value)),
454 _ => self.deserialize_any(visitor),
455 }
456 }
457 };
458}
459
460impl<'de, 'a> serde::Deserializer<'de> for ValueDeserializer<'a>
461where
462 'a: 'de,
463{
464 type Error = serde::de::value::Error;
465
466 fn deserialize_any<V: serde::de::Visitor<'de>>(
467 self,
468 visitor: V,
469 ) -> Result<V::Value, Self::Error> {
470 match self.0 {
471 Value::Null => visitor.visit_unit(),
472 Value::Bool(value) => visitor.visit_bool(*value),
473 Value::Integer(value) => visitor.visit_i64(*value),
474 Value::Unsigned(value) => visitor.visit_u64(*value),
475 Value::Float(value) => visitor.visit_f64(*value),
476 Value::String(value) => visitor.visit_string(value.clone()),
477 Value::Array(values) => visitor.visit_seq(BorrowedSeqAccess {
478 values: values.iter(),
479 }),
480 Value::Object(values) => visitor.visit_map(BorrowedMapAccess {
481 values: values.iter(),
482 pending: None,
483 }),
484 }
485 }
486
487 fn deserialize_option<V: serde::de::Visitor<'de>>(
488 self,
489 visitor: V,
490 ) -> Result<V::Value, Self::Error> {
491 if self.0.is_null() {
492 visitor.visit_none()
493 } else {
494 visitor.visit_some(self)
495 }
496 }
497
498 fn deserialize_enum<V: serde::de::Visitor<'de>>(
499 self,
500 _name: &'static str,
501 _variants: &'static [&'static str],
502 visitor: V,
503 ) -> Result<V::Value, Self::Error> {
504 match self.0 {
505 Value::String(variant) => visitor.visit_enum(EnumAccess {
506 variant: variant.clone(),
507 value: None,
508 }),
509 Value::Object(values) if values.len() == 1 => {
510 let mut entries = values.iter();
511 if let Some((variant, value)) = entries.next() {
512 visitor.visit_enum(EnumAccess {
513 variant: variant.clone(),
514 value: Some(value),
515 })
516 } else {
517 Err(de::Error::custom("missing enum variant"))
518 }
519 }
520 _ => Err(de::Error::custom(
521 "expected enum variant string or single-key object",
522 )),
523 }
524 }
525
526 fn deserialize_bool<V: serde::de::Visitor<'de>>(
527 self,
528 visitor: V,
529 ) -> Result<V::Value, Self::Error> {
530 match self.0 {
531 Value::String(value) => match value.to_ascii_lowercase().as_str() {
532 "true" | "yes" | "on" | "1" => visitor.visit_bool(true),
533 "false" | "no" | "off" | "0" => visitor.visit_bool(false),
534 _ => Err(de::Error::custom("invalid boolean string")),
535 },
536 _ => self.deserialize_any(visitor),
537 }
538 }
539
540 string_number!(deserialize_i8, i8, visit_i8);
541 string_number!(deserialize_i16, i16, visit_i16);
542 string_number!(deserialize_i32, i32, visit_i32);
543 string_number!(deserialize_i64, i64, visit_i64);
544 string_number!(deserialize_i128, i128, visit_i128);
545 string_number!(deserialize_u8, u8, visit_u8);
546 string_number!(deserialize_u16, u16, visit_u16);
547 string_number!(deserialize_u32, u32, visit_u32);
548 string_number!(deserialize_u64, u64, visit_u64);
549 string_number!(deserialize_u128, u128, visit_u128);
550 string_number!(deserialize_f32, f32, visit_f32);
551 string_number!(deserialize_f64, f64, visit_f64);
552
553 serde::forward_to_deserialize_any! {
554 char str string bytes byte_buf
555 unit unit_struct newtype_struct seq tuple tuple_struct map struct identifier ignored_any
556 }
557}
558
559struct BorrowedSeqAccess<'a> {
560 values: std::slice::Iter<'a, Value>,
561}
562
563impl<'de, 'a> serde::de::SeqAccess<'de> for BorrowedSeqAccess<'a>
564where
565 'a: 'de,
566{
567 type Error = serde::de::value::Error;
568 fn next_element_seed<T: serde::de::DeserializeSeed<'de>>(
569 &mut self,
570 seed: T,
571 ) -> Result<Option<T::Value>, Self::Error> {
572 self.values
573 .next()
574 .map(|value| seed.deserialize(ValueDeserializer(value)))
575 .transpose()
576 }
577}
578
579struct BorrowedMapAccess<'a> {
580 values: std::collections::btree_map::Iter<'a, String, Value>,
581 pending: Option<&'a Value>,
582}
583
584impl<'de, 'a> serde::de::MapAccess<'de> for BorrowedMapAccess<'a>
585where
586 'a: 'de,
587{
588 type Error = serde::de::value::Error;
589 fn next_key_seed<K: serde::de::DeserializeSeed<'de>>(
590 &mut self,
591 seed: K,
592 ) -> Result<Option<K::Value>, Self::Error> {
593 match self.values.next() {
594 Some((key, value)) => {
595 self.pending = Some(value);
596 seed.deserialize(serde::de::IntoDeserializer::into_deserializer(key.clone()))
597 .map(Some)
598 }
599 None => Ok(None),
600 }
601 }
602 fn next_value_seed<V: serde::de::DeserializeSeed<'de>>(
603 &mut self,
604 seed: V,
605 ) -> Result<V::Value, Self::Error> {
606 let value = self
607 .pending
608 .take()
609 .ok_or_else(|| de::Error::custom("map value without key"))?;
610 seed.deserialize(ValueDeserializer(value))
611 }
612}
613
614struct EnumAccess<'a> {
615 variant: String,
616 value: Option<&'a Value>,
617}
618
619impl<'de, 'a> serde::de::EnumAccess<'de> for EnumAccess<'a>
620where
621 'a: 'de,
622{
623 type Error = serde::de::value::Error;
624 type Variant = VariantAccess<'a>;
625 fn variant_seed<V: serde::de::DeserializeSeed<'de>>(
626 self,
627 seed: V,
628 ) -> Result<(V::Value, Self::Variant), Self::Error> {
629 let variant =
630 seed.deserialize(serde::de::IntoDeserializer::into_deserializer(self.variant))?;
631 Ok((variant, VariantAccess { value: self.value }))
632 }
633}
634
635struct VariantAccess<'a> {
636 value: Option<&'a Value>,
637}
638
639#[cfg(test)]
640mod tests {
641 use super::{from_value, to_value};
642 use crate::document::Value;
643 use serde::{Deserialize, Serialize};
644
645 #[derive(Debug, PartialEq, Serialize, Deserialize)]
646 struct Config {
647 name: String,
648 enabled: Option<bool>,
649 #[serde(flatten)]
650 extra: Extra,
651 }
652
653 #[derive(Debug, PartialEq, Serialize, Deserialize)]
654 struct Extra {
655 count: u64,
656 }
657
658 #[derive(Debug, PartialEq, Serialize, Deserialize)]
659 enum Mode {
660 Fast,
661 Custom { level: u32 },
662 }
663
664 #[test]
665 fn round_trips_struct_optional_flatten_and_enum() {
666 let value = Value::Object(std::collections::BTreeMap::from([
667 ("name".to_string(), Value::String("demo".to_string())),
668 ("enabled".to_string(), Value::Null),
669 ("count".to_string(), Value::Unsigned(9)),
670 ]));
671 let config: Config = from_value(&value, "root").unwrap_or_else(|error| panic!("{error}"));
672 assert_eq!(config.name, "demo");
673 assert_eq!(config.enabled, None);
674 assert_eq!(config.extra.count, 9);
675 let mode = Mode::Custom { level: 3 };
676 assert_eq!(
677 from_value(&to_value(&mode).unwrap_or(Value::Null), "mode").unwrap_or(Mode::Fast),
678 mode
679 );
680 }
681
682 #[derive(Debug, Deserialize)]
683 #[serde(deny_unknown_fields)]
684 struct Strict {
685 #[allow(dead_code)]
686 name: String,
687 }
688
689 #[test]
690 fn reports_typed_path_and_unknown_field() {
691 let value = Value::Object(std::collections::BTreeMap::from([
692 ("name".to_string(), Value::String("demo".to_string())),
693 ("extra".to_string(), Value::Bool(true)),
694 ]));
695 let error = from_value::<Strict>(&value, "settings").expect_err("unknown field must fail");
696 assert!(error.to_string().contains("settings"));
697 assert!(error.to_string().contains("unknown field"));
698 }
699
700 #[test]
701 fn directs_string_leaves_into_typed_scalars() {
702 let value = Value::Object(std::collections::BTreeMap::from([
703 ("enabled".to_string(), Value::String("yes".to_string())),
704 ("count".to_string(), Value::String("42".to_string())),
705 ]));
706 #[derive(Debug, Deserialize, PartialEq)]
707 struct StringBacked {
708 enabled: bool,
709 count: u64,
710 }
711 assert_eq!(
712 from_value::<StringBacked>(&value, "env").unwrap_or_else(|error| panic!("{error}")),
713 StringBacked {
714 enabled: true,
715 count: 42
716 }
717 );
718 }
719}
720impl<'de, 'a> serde::de::VariantAccess<'de> for VariantAccess<'a>
721where
722 'a: 'de,
723{
724 type Error = serde::de::value::Error;
725 fn unit_variant(self) -> Result<(), Self::Error> {
726 if self.value.is_none() {
727 Ok(())
728 } else {
729 Err(de::Error::custom("expected unit variant"))
730 }
731 }
732 fn newtype_variant_seed<T: serde::de::DeserializeSeed<'de>>(
733 self,
734 seed: T,
735 ) -> Result<T::Value, Self::Error> {
736 seed.deserialize(ValueDeserializer(
737 self.value
738 .ok_or_else(|| de::Error::custom("missing newtype value"))?,
739 ))
740 }
741 fn tuple_variant<V: serde::de::Visitor<'de>>(
742 self,
743 _len: usize,
744 visitor: V,
745 ) -> Result<V::Value, Self::Error> {
746 ValueDeserializer(
747 self.value
748 .ok_or_else(|| de::Error::custom("missing tuple value"))?,
749 )
750 .deserialize_seq(visitor)
751 }
752 fn struct_variant<V: serde::de::Visitor<'de>>(
753 self,
754 _fields: &'static [&'static str],
755 visitor: V,
756 ) -> Result<V::Value, Self::Error> {
757 ValueDeserializer(
758 self.value
759 .ok_or_else(|| de::Error::custom("missing struct value"))?,
760 )
761 .deserialize_map(visitor)
762 }
763}