Skip to main content

agent_first_data/document/
typed.rs

1//! Fallible serde adapters over the format-independent [`Value`] IR.
2
3#![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
12/// Deserialize a typed configuration from a value view.
13pub 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
17/// Serialize a typed configuration into the format-independent value view.
18pub 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}