Skip to main content

structfs_serde_store/
value_serde.rs

1//! Direct, checked `structfs-serde/1` conversion.
2use crate::limits::{ensure, Budget, Failure, Limits, Result};
3use serde::{de, ser, Deserialize, Serialize};
4use std::collections::BTreeMap;
5use structfs_core_store::{CodecErrorKind as K, CodecOperation, Error, Format, Value};
6
7pub fn to_value_with_limits<T: Serialize + ?Sized>(
8    value: &T,
9    limits: &Limits,
10) -> std::result::Result<Value, Error> {
11    value
12        .serialize(Serializer {
13            budget: &mut Budget::new(limits),
14            depth: 0,
15            key: false,
16        })
17        .map_err(|e| e.core(&Format::VALUE, CodecOperation::Encode, limits))
18}
19pub fn from_value_with_limits<T: de::DeserializeOwned>(
20    value: Value,
21    limits: &Limits,
22) -> std::result::Result<T, Error> {
23    Budget::new(limits)
24        .tree(&value, 0)
25        .and_then(|()| T::deserialize(Deserializer(&value)))
26        .map_err(|e| e.core(&Format::VALUE, CodecOperation::Decode, limits))
27}
28pub fn to_value<T: Serialize + ?Sized>(value: &T) -> std::result::Result<Value, Error> {
29    to_value_with_limits(value, &Limits::default())
30}
31pub fn from_value<T: de::DeserializeOwned>(value: Value) -> std::result::Result<T, Error> {
32    from_value_with_limits(value, &Limits::default())
33}
34
35struct Serializer<'a, 'b> {
36    budget: &'a mut Budget<'b>,
37    depth: usize,
38    key: bool,
39}
40impl<'a, 'b> Serializer<'a, 'b> {
41    fn scalar(self, v: Value) -> Result<Value> {
42        ensure(!self.key, K::UnsupportedValue)?;
43        self.budget.node(self.depth)?;
44        Ok(v)
45    }
46    fn compound(self, len: Option<usize>, map: bool) -> Result<Compound<'a, 'b>> {
47        ensure(!self.key, K::UnsupportedValue)?;
48        self.budget.node(self.depth)?;
49        if let Some(n) = len {
50            self.budget.entries(n)?;
51        }
52        Ok(Compound {
53            serializer: self,
54            expected: len,
55            array: Vec::new(),
56            map: BTreeMap::new(),
57            key: None,
58            is_map: map,
59            variant: None,
60        })
61    }
62}
63impl<'a, 'b> ser::Serializer for Serializer<'a, 'b> {
64    type Ok = Value;
65    type Error = Failure;
66    type SerializeSeq = Compound<'a, 'b>;
67    type SerializeTuple = Compound<'a, 'b>;
68    type SerializeTupleStruct = Compound<'a, 'b>;
69    type SerializeTupleVariant = Compound<'a, 'b>;
70    type SerializeMap = Compound<'a, 'b>;
71    type SerializeStruct = Compound<'a, 'b>;
72    type SerializeStructVariant = Compound<'a, 'b>;
73    fn serialize_bool(self, v: bool) -> Result<Value> {
74        self.scalar(Value::Bool(v))
75    }
76    fn serialize_i8(self, v: i8) -> Result<Value> {
77        self.serialize_i64(v.into())
78    }
79    fn serialize_i16(self, v: i16) -> Result<Value> {
80        self.serialize_i64(v.into())
81    }
82    fn serialize_i32(self, v: i32) -> Result<Value> {
83        self.serialize_i64(v.into())
84    }
85    fn serialize_i64(self, v: i64) -> Result<Value> {
86        self.scalar(Value::Integer(v))
87    }
88    fn serialize_i128(self, v: i128) -> Result<Value> {
89        if v < 0 {
90            self.serialize_i64(v.try_into().map_err(|_| Failure::new(K::OutOfRange))?)
91        } else {
92            self.serialize_u64(v.try_into().map_err(|_| Failure::new(K::OutOfRange))?)
93        }
94    }
95    fn serialize_u8(self, v: u8) -> Result<Value> {
96        self.serialize_u64(v.into())
97    }
98    fn serialize_u16(self, v: u16) -> Result<Value> {
99        self.serialize_u64(v.into())
100    }
101    fn serialize_u32(self, v: u32) -> Result<Value> {
102        self.serialize_u64(v.into())
103    }
104    fn serialize_u64(self, v: u64) -> Result<Value> {
105        self.scalar(Value::from(v))
106    }
107    fn serialize_u128(self, v: u128) -> Result<Value> {
108        self.serialize_u64(v.try_into().map_err(|_| Failure::new(K::OutOfRange))?)
109    }
110    fn serialize_f32(self, v: f32) -> Result<Value> {
111        self.serialize_f64(v.into())
112    }
113    fn serialize_f64(self, v: f64) -> Result<Value> {
114        self.scalar(Value::from(v))
115    }
116    fn serialize_char(self, v: char) -> Result<Value> {
117        ensure(!self.key, K::UnsupportedValue)?;
118        self.serialize_str(v.encode_utf8(&mut [0; 4]))
119    }
120    fn serialize_str(self, v: &str) -> Result<Value> {
121        if !self.key {
122            self.budget.node(self.depth)?;
123        }
124        self.budget.payload(v.len(), false)?;
125        Ok(Value::String(v.into()))
126    }
127    fn serialize_bytes(self, v: &[u8]) -> Result<Value> {
128        ensure(!self.key, K::UnsupportedValue)?;
129        self.budget.payload(v.len(), true)?;
130        self.scalar(Value::Bytes(v.into()))
131    }
132    fn serialize_none(self) -> Result<Value> {
133        self.scalar(Value::Null)
134    }
135    fn serialize_some<T: Serialize + ?Sized>(self, v: &T) -> Result<Value> {
136        ensure(!self.key, K::UnsupportedValue)?;
137        let value = v.serialize(self)?;
138        ensure(!value.is_null(), K::AmbiguousOption)?;
139        Ok(value)
140    }
141    fn serialize_unit(self) -> Result<Value> {
142        self.scalar(Value::Null)
143    }
144    fn serialize_unit_struct(self, _: &'static str) -> Result<Value> {
145        self.serialize_unit()
146    }
147    fn serialize_unit_variant(self, _: &'static str, _: u32, v: &'static str) -> Result<Value> {
148        ensure(!self.key, K::UnsupportedValue)?;
149        self.serialize_str(v)
150    }
151    fn serialize_newtype_struct<T: Serialize + ?Sized>(
152        self,
153        _: &'static str,
154        v: &T,
155    ) -> Result<Value> {
156        v.serialize(self)
157    }
158    fn serialize_newtype_variant<T: Serialize + ?Sized>(
159        self,
160        _: &'static str,
161        _: u32,
162        k: &'static str,
163        v: &T,
164    ) -> Result<Value> {
165        let mut c = self.compound(Some(1), true)?;
166        ser::SerializeMap::serialize_entry(&mut c, k, v)?;
167        c.finish()
168    }
169    fn serialize_seq(self, n: Option<usize>) -> Result<Self::SerializeSeq> {
170        self.compound(n, false)
171    }
172    fn serialize_tuple(self, n: usize) -> Result<Self::SerializeTuple> {
173        self.compound(Some(n), false)
174    }
175    fn serialize_tuple_struct(
176        self,
177        _: &'static str,
178        n: usize,
179    ) -> Result<Self::SerializeTupleStruct> {
180        self.compound(Some(n), false)
181    }
182    fn serialize_tuple_variant(
183        self,
184        _: &'static str,
185        _: u32,
186        k: &'static str,
187        n: usize,
188    ) -> Result<Self::SerializeTupleVariant> {
189        self.variant(k, n, false)
190    }
191    fn serialize_map(self, n: Option<usize>) -> Result<Self::SerializeMap> {
192        self.compound(n, true)
193    }
194    fn serialize_struct(self, _: &'static str, n: usize) -> Result<Self::SerializeStruct> {
195        self.compound(Some(n), true)
196    }
197    fn serialize_struct_variant(
198        self,
199        _: &'static str,
200        _: u32,
201        k: &'static str,
202        n: usize,
203    ) -> Result<Self::SerializeStructVariant> {
204        self.variant(k, n, true)
205    }
206    fn is_human_readable(&self) -> bool {
207        true
208    }
209    fn collect_str<T: std::fmt::Display + ?Sized>(self, value: &T) -> Result<Value> {
210        use std::fmt::Write;
211        ensure(!self.key, K::UnsupportedValue)?;
212        struct Bounded {
213            text: String,
214            max: usize,
215        }
216        impl std::fmt::Write for Bounded {
217            fn write_str(&mut self, s: &str) -> std::fmt::Result {
218                if s.len() > self.max.saturating_sub(self.text.len()) {
219                    return Err(std::fmt::Error);
220                }
221                self.text.push_str(s);
222                Ok(())
223            }
224        }
225        let max = self
226            .budget
227            .limits
228            .max_string_bytes
229            .min(self.budget.limits.max_allocation_bytes)
230            .min(self.budget.limits.max_work);
231        let mut out = Bounded {
232            text: String::new(),
233            max,
234        };
235        write!(&mut out, "{value}").map_err(|_| Failure::new(K::ResourceLimit))?;
236        self.serialize_str(&out.text)
237    }
238}
239impl<'a, 'b> Serializer<'a, 'b> {
240    fn variant(mut self, k: &'static str, n: usize, map: bool) -> Result<Compound<'a, 'b>> {
241        ensure(!self.key, K::UnsupportedValue)?;
242        self.budget.node(self.depth)?;
243        self.budget.entries(1)?;
244        self.budget.payload(k.len(), false)?;
245        self.depth += 1;
246        let mut c = self.compound(Some(n), map)?;
247        c.variant = Some(k);
248        Ok(c)
249    }
250}
251struct Compound<'a, 'b> {
252    serializer: Serializer<'a, 'b>,
253    expected: Option<usize>,
254    array: Vec<Value>,
255    map: BTreeMap<String, Value>,
256    key: Option<String>,
257    is_map: bool,
258    variant: Option<&'static str>,
259}
260impl Compound<'_, '_> {
261    fn element<T: Serialize + ?Sized>(&mut self, v: &T) -> Result<()> {
262        self.serializer.budget.entries(self.array.len() + 1)?;
263        let value = v
264            .serialize(Serializer {
265                budget: self.serializer.budget,
266                depth: self.serializer.depth + 1,
267                key: false,
268            })
269            .map_err(|e| e.at(format_args!("[{}]", self.array.len())))?;
270        self.array.push(value);
271        Ok(())
272    }
273    fn finish(self) -> Result<Value> {
274        ensure(self.key.is_none(), K::TypeMismatch)?;
275        let n = if self.is_map {
276            self.map.len()
277        } else {
278            self.array.len()
279        };
280        ensure(self.expected.is_none_or(|e| e == n), K::TypeMismatch)?;
281        let v = if self.is_map {
282            Value::Map(self.map)
283        } else {
284            Value::Array(self.array)
285        };
286        Ok(if let Some(k) = self.variant {
287            Value::Map(BTreeMap::from([(k.to_owned(), v)]))
288        } else {
289            v
290        })
291    }
292}
293impl ser::SerializeMap for Compound<'_, '_> {
294    type Ok = Value;
295    type Error = Failure;
296    fn serialize_key<T: Serialize + ?Sized>(&mut self, k: &T) -> Result<()> {
297        ensure(self.key.is_none(), K::TypeMismatch)?;
298        self.serializer.budget.entries(self.map.len() + 1)?;
299        let key = k.serialize(Serializer {
300            budget: self.serializer.budget,
301            depth: self.serializer.depth,
302            key: true,
303        })?;
304        let Value::String(key) = key else {
305            return Err(Failure::new(K::UnsupportedValue));
306        };
307        self.serializer
308            .budget
309            .key_work(key.len(), self.map.len() + 1)?;
310        ensure(!self.map.contains_key(&key), K::DuplicateKey)?;
311        self.key = Some(key);
312        Ok(())
313    }
314    fn serialize_value<T: Serialize + ?Sized>(&mut self, v: &T) -> Result<()> {
315        let k = self.key.take().ok_or(Failure::new(K::TypeMismatch))?;
316        let v = v
317            .serialize(Serializer {
318                budget: self.serializer.budget,
319                depth: self.serializer.depth + 1,
320                key: false,
321            })
322            .map_err(|e| e.at(format_args!("[{k:?}]")))?;
323        self.map.insert(k, v);
324        Ok(())
325    }
326    fn end(self) -> Result<Value> {
327        self.finish()
328    }
329}
330macro_rules! seq_impl {
331    ($trait:ident,$method:ident) => {
332        impl ser::$trait for Compound<'_, '_> {
333            type Ok = Value;
334            type Error = Failure;
335            fn $method<T: Serialize + ?Sized>(&mut self, v: &T) -> Result<()> {
336                self.element(v)
337            }
338            fn end(self) -> Result<Value> {
339                self.finish()
340            }
341        }
342    };
343}
344seq_impl!(SerializeSeq, serialize_element);
345seq_impl!(SerializeTuple, serialize_element);
346seq_impl!(SerializeTupleStruct, serialize_field);
347seq_impl!(SerializeTupleVariant, serialize_field);
348macro_rules! struct_impl {
349    ($trait:ident) => {
350        impl ser::$trait for Compound<'_, '_> {
351            type Ok = Value;
352            type Error = Failure;
353            fn serialize_field<T: Serialize + ?Sized>(
354                &mut self,
355                k: &'static str,
356                v: &T,
357            ) -> Result<()> {
358                ser::SerializeMap::serialize_entry(self, k, v)
359            }
360            fn end(self) -> Result<Value> {
361                self.finish()
362            }
363        }
364    };
365}
366struct_impl!(SerializeStruct);
367struct_impl!(SerializeStructVariant);
368
369struct Deserializer<'de>(&'de Value);
370macro_rules! integer {
371    ($method:ident,$visit:ident,$ty:ty) => {
372        fn $method<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
373            let n = match self.0 {
374                Value::Integer(n) => *n as i128,
375                Value::Unsigned(n) => *n as i128,
376                _ => return Err(Failure::new(K::TypeMismatch)),
377            };
378            v.$visit(<$ty>::try_from(n).map_err(|_| Failure::new(K::OutOfRange))?)
379        }
380    };
381}
382impl<'de> de::Deserializer<'de> for Deserializer<'de> {
383    type Error = Failure;
384    fn deserialize_any<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
385        match self.0 {
386            Value::Null => v.visit_unit(),
387            Value::Bool(x) => v.visit_bool(*x),
388            Value::Integer(x) => v.visit_i64(*x),
389            Value::Unsigned(x) if *x <= i64::MAX as u64 => v.visit_i64(*x as i64),
390            Value::Unsigned(x) => v.visit_u64(*x),
391            Value::Float(x) => v.visit_f64(if x.is_nan() {
392                f64::from_bits(0x7ff8000000000000)
393            } else {
394                *x
395            }),
396            Value::String(x) => v.visit_borrowed_str(x),
397            Value::Bytes(x) => v.visit_borrowed_bytes(x),
398            Value::Array(_) => self.deserialize_seq(v),
399            Value::Map(_) => self.deserialize_map(v),
400            _ => Err(Failure::new(K::UnsupportedValue)),
401        }
402    }
403    integer!(deserialize_i8, visit_i8, i8);
404    integer!(deserialize_i16, visit_i16, i16);
405    integer!(deserialize_i32, visit_i32, i32);
406    integer!(deserialize_i64, visit_i64, i64);
407    integer!(deserialize_i128, visit_i128, i128);
408    integer!(deserialize_u8, visit_u8, u8);
409    integer!(deserialize_u16, visit_u16, u16);
410    integer!(deserialize_u32, visit_u32, u32);
411    integer!(deserialize_u64, visit_u64, u64);
412    integer!(deserialize_u128, visit_u128, u128);
413    fn deserialize_bool<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
414        if let Value::Bool(x) = self.0 {
415            v.visit_bool(*x)
416        } else {
417            Err(Failure::new(K::TypeMismatch))
418        }
419    }
420    fn deserialize_f64<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
421        if let Value::Float(_) = self.0 {
422            self.deserialize_any(v)
423        } else {
424            Err(Failure::new(K::TypeMismatch))
425        }
426    }
427    fn deserialize_f32<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
428        let Value::Float(x) = self.0 else {
429            return Err(Failure::new(K::TypeMismatch));
430        };
431        if x.is_nan() {
432            return v.visit_f32(f32::from_bits(0x7fc00000));
433        }
434        let f = *x as f32;
435        ensure((f as f64).to_bits() == x.to_bits(), K::OutOfRange)?;
436        v.visit_f32(f)
437    }
438    fn deserialize_str<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
439        if let Value::String(x) = self.0 {
440            v.visit_borrowed_str(x)
441        } else {
442            Err(Failure::new(K::TypeMismatch))
443        }
444    }
445    fn deserialize_string<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
446        self.deserialize_str(v)
447    }
448    fn deserialize_char<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
449        let Value::String(x) = self.0 else {
450            return Err(Failure::new(K::TypeMismatch));
451        };
452        let mut c = x.chars();
453        let first = c.next().ok_or(Failure::new(K::TypeMismatch))?;
454        ensure(c.next().is_none(), K::TypeMismatch)?;
455        v.visit_char(first)
456    }
457    fn deserialize_bytes<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
458        if let Value::Bytes(x) = self.0 {
459            v.visit_borrowed_bytes(x)
460        } else {
461            Err(Failure::new(K::TypeMismatch))
462        }
463    }
464    fn deserialize_byte_buf<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
465        self.deserialize_bytes(v)
466    }
467    fn deserialize_option<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
468        if self.0.is_null() {
469            v.visit_none()
470        } else {
471            v.visit_some(self)
472        }
473    }
474    fn deserialize_unit<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
475        ensure(self.0.is_null(), K::TypeMismatch)?;
476        v.visit_unit()
477    }
478    fn deserialize_unit_struct<V: de::Visitor<'de>>(
479        self,
480        _: &'static str,
481        v: V,
482    ) -> Result<V::Value> {
483        self.deserialize_unit(v)
484    }
485    fn deserialize_newtype_struct<V: de::Visitor<'de>>(
486        self,
487        _: &'static str,
488        v: V,
489    ) -> Result<V::Value> {
490        v.visit_newtype_struct(self)
491    }
492    fn deserialize_seq<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
493        let Value::Array(a) = self.0 else {
494            return Err(Failure::new(K::TypeMismatch));
495        };
496        let mut access = Sequence(a.iter(), 0);
497        let result = v.visit_seq(&mut access)?;
498        ensure(access.0.len() == 0, K::TypeMismatch)?;
499        Ok(result)
500    }
501    fn deserialize_tuple<V: de::Visitor<'de>>(self, n: usize, v: V) -> Result<V::Value> {
502        ensure(
503            matches!(self.0,Value::Array(a) if a.len()==n),
504            K::TypeMismatch,
505        )?;
506        self.deserialize_seq(v)
507    }
508    fn deserialize_tuple_struct<V: de::Visitor<'de>>(
509        self,
510        _: &'static str,
511        n: usize,
512        v: V,
513    ) -> Result<V::Value> {
514        self.deserialize_tuple(n, v)
515    }
516    fn deserialize_map<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
517        let Value::Map(m) = self.0 else {
518            return Err(Failure::new(K::TypeMismatch));
519        };
520        let mut access = Mapping {
521            iter: m.iter(),
522            pending: None,
523        };
524        let result = v.visit_map(&mut access)?;
525        ensure(
526            access.iter.len() == 0 && access.pending.is_none(),
527            K::TypeMismatch,
528        )?;
529        Ok(result)
530    }
531    fn deserialize_struct<V: de::Visitor<'de>>(
532        self,
533        _: &'static str,
534        _: &'static [&'static str],
535        v: V,
536    ) -> Result<V::Value> {
537        self.deserialize_map(v)
538    }
539    fn deserialize_enum<V: de::Visitor<'de>>(
540        self,
541        _: &'static str,
542        _: &'static [&'static str],
543        v: V,
544    ) -> Result<V::Value> {
545        let (name, payload) = match self.0 {
546            Value::String(s) => (s.as_str(), None),
547            Value::Map(m) if m.len() == 1 => {
548                let (k, v) = m.first_key_value().unwrap();
549                (k.as_str(), Some(v))
550            }
551            _ => return Err(Failure::new(K::TypeMismatch)),
552        };
553        v.visit_enum(Enum { name, payload })
554    }
555    fn deserialize_identifier<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
556        self.deserialize_str(v)
557    }
558    fn deserialize_ignored_any<V: de::Visitor<'de>>(self, v: V) -> Result<V::Value> {
559        v.visit_unit()
560    }
561    fn is_human_readable(&self) -> bool {
562        true
563    }
564}
565struct Sequence<'a>(std::slice::Iter<'a, Value>, usize);
566impl<'de> de::SeqAccess<'de> for Sequence<'de> {
567    type Error = Failure;
568    fn next_element_seed<T: de::DeserializeSeed<'de>>(&mut self, s: T) -> Result<Option<T::Value>> {
569        let index = self.1;
570        self.1 += 1;
571        self.0
572            .next()
573            .map(|v| {
574                s.deserialize(Deserializer(v))
575                    .map_err(|e| e.at(format_args!("[{index}]")))
576            })
577            .transpose()
578    }
579    fn size_hint(&self) -> Option<usize> {
580        Some(self.0.len())
581    }
582}
583struct Mapping<'a> {
584    iter: std::collections::btree_map::Iter<'a, String, Value>,
585    pending: Option<(&'a str, &'a Value)>,
586}
587impl<'de> de::MapAccess<'de> for Mapping<'de> {
588    type Error = Failure;
589    fn next_key_seed<T: de::DeserializeSeed<'de>>(&mut self, s: T) -> Result<Option<T::Value>> {
590        ensure(self.pending.is_none(), K::TypeMismatch)?;
591        if let Some((k, v)) = self.iter.next() {
592            self.pending = Some((k, v));
593            s.deserialize(de::value::BorrowedStrDeserializer::<Failure>::new(k))
594                .map(Some)
595        } else {
596            Ok(None)
597        }
598    }
599    fn next_value_seed<T: de::DeserializeSeed<'de>>(&mut self, s: T) -> Result<T::Value> {
600        let (key, value) = self.pending.take().ok_or(Failure::new(K::TypeMismatch))?;
601        s.deserialize(Deserializer(value))
602            .map_err(|e| e.at(format_args!("[{key:?}]")))
603    }
604    fn size_hint(&self) -> Option<usize> {
605        Some(self.iter.len())
606    }
607}
608struct Enum<'a> {
609    name: &'a str,
610    payload: Option<&'a Value>,
611}
612impl<'de> de::EnumAccess<'de> for Enum<'de> {
613    type Error = Failure;
614    type Variant = Self;
615    fn variant_seed<T: de::DeserializeSeed<'de>>(self, s: T) -> Result<(T::Value, Self)> {
616        let n = s.deserialize(de::value::BorrowedStrDeserializer::<Failure>::new(
617            self.name,
618        ))?;
619        Ok((n, self))
620    }
621}
622impl<'de> de::VariantAccess<'de> for Enum<'de> {
623    type Error = Failure;
624    fn unit_variant(self) -> Result<()> {
625        ensure(self.payload.is_none(), K::TypeMismatch)
626    }
627    fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(self, s: T) -> Result<T::Value> {
628        s.deserialize(Deserializer(
629            self.payload.ok_or(Failure::new(K::TypeMismatch))?,
630        ))
631    }
632    fn tuple_variant<V: de::Visitor<'de>>(self, n: usize, v: V) -> Result<V::Value> {
633        de::Deserializer::deserialize_tuple(
634            Deserializer(self.payload.ok_or(Failure::new(K::TypeMismatch))?),
635            n,
636            v,
637        )
638    }
639    fn struct_variant<V: de::Visitor<'de>>(
640        self,
641        _: &'static [&'static str],
642        v: V,
643    ) -> Result<V::Value> {
644        de::Deserializer::deserialize_map(
645            Deserializer(self.payload.ok_or(Failure::new(K::TypeMismatch))?),
646            v,
647        )
648    }
649}
650
651/// Schema-visible option that can preserve Some(()) and nested optional states.
652#[derive(Debug, Clone, PartialEq, Eq)]
653pub struct ExplicitOption<T>(pub Option<T>);
654impl<T: Serialize> Serialize for ExplicitOption<T> {
655    fn serialize<S: ser::Serializer>(&self, s: S) -> std::result::Result<S::Ok, S::Error> {
656        use ser::SerializeMap;
657        let mut m = s.serialize_map(Some(if self.0.is_some() { 2 } else { 1 }))?;
658        m.serialize_entry("kind", if self.0.is_some() { "some" } else { "none" })?;
659        if let Some(v) = &self.0 {
660            m.serialize_entry("value", v)?;
661        }
662        m.end()
663    }
664}
665impl<'de, T: Deserialize<'de>> Deserialize<'de> for ExplicitOption<T> {
666    fn deserialize<D: de::Deserializer<'de>>(d: D) -> std::result::Result<Self, D::Error> {
667        struct Visitor<T>(std::marker::PhantomData<T>);
668        impl<'de, T: Deserialize<'de>> de::Visitor<'de> for Visitor<T> {
669            type Value = ExplicitOption<T>;
670            fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
671                f.write_str("an explicit option map")
672            }
673            fn visit_map<A: de::MapAccess<'de>>(
674                self,
675                mut a: A,
676            ) -> std::result::Result<Self::Value, A::Error> {
677                let mut kind: Option<String> = None;
678                let mut value: Option<T> = None;
679                while let Some(k) = a.next_key::<String>()? {
680                    match k.as_str() {
681                        "kind" if kind.is_none() => kind = Some(a.next_value()?),
682                        "value" if value.is_none() => value = Some(a.next_value()?),
683                        _ => {
684                            return Err(de::Error::custom(
685                                "extra or repeated explicit option field",
686                            ))
687                        }
688                    }
689                }
690                match (kind.as_deref(), value) {
691                    (Some("none"), None) => Ok(ExplicitOption(None)),
692                    (Some("some"), Some(v)) => Ok(ExplicitOption(Some(v))),
693                    _ => Err(de::Error::custom("invalid explicit option shape")),
694                }
695            }
696        }
697        d.deserialize_map(Visitor(std::marker::PhantomData))
698    }
699}