Skip to main content

md_tmpl_core/
serde_support.rs

1//! Serde integration for converting `Serialize` types into [`Value`].
2//!
3//! Enabled by the `serde` feature flag.
4
5use alloc::{
6    string::{String, ToString},
7    sync::Arc,
8    vec::Vec,
9};
10use core::fmt;
11
12use serde::ser::{self, Serialize};
13
14use crate::{compat::HashMap, value::Value};
15
16/// Convert any `Serialize` type into a [`Value`].
17///
18/// Structs become `Struct`, vectors become `List`, strings/numbers/bools map
19/// to their corresponding `Value` variants.
20///
21/// # Errors
22///
23/// Returns an error if the type contains unsupported serde data (e.g. bytes).
24///
25/// # Examples
26///
27/// ```
28/// use md_tmpl_core::Value;
29/// use serde::Serialize;
30///
31/// #[derive(Serialize)]
32/// struct Agent {
33///     name: String,
34///     score: i64,
35/// }
36///
37/// let agent = Agent {
38///     name: "Alice".into(),
39///     score: 95,
40/// };
41/// let val = md_tmpl_core::to_value(&agent).unwrap();
42/// assert_eq!(val.get_field("name").unwrap().to_string(), "Alice");
43/// assert_eq!(val.get_field("score").unwrap().to_string(), "95");
44/// ```
45pub fn to_value<T: Serialize>(value: &T) -> Result<Value, SerError> {
46    value.serialize(ValueSerializer)
47}
48
49/// Error type for serde-to-Value conversion.
50#[derive(Debug)]
51pub struct SerError(String);
52
53impl fmt::Display for SerError {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        f.write_str(&self.0)
56    }
57}
58
59impl core::error::Error for SerError {}
60
61impl ser::Error for SerError {
62    fn custom<T: fmt::Display>(msg: T) -> Self {
63        Self(msg.to_string())
64    }
65}
66
67// ---------------------------------------------------------------------------
68// Serializer implementation
69// ---------------------------------------------------------------------------
70
71struct ValueSerializer;
72
73impl ser::Serializer for ValueSerializer {
74    type Ok = Value;
75    type Error = SerError;
76    type SerializeSeq = SeqBuilder;
77    type SerializeTuple = SeqBuilder;
78    type SerializeTupleStruct = SeqBuilder;
79    type SerializeTupleVariant = SeqBuilder;
80    type SerializeMap = MapBuilder;
81    type SerializeStruct = MapBuilder;
82    type SerializeStructVariant = MapBuilder;
83
84    fn serialize_bool(self, v: bool) -> Result<Value, SerError> {
85        Ok(Value::Bool(v))
86    }
87
88    fn serialize_i8(self, v: i8) -> Result<Value, SerError> {
89        Ok(Value::Int(i64::from(v)))
90    }
91    fn serialize_i16(self, v: i16) -> Result<Value, SerError> {
92        Ok(Value::Int(i64::from(v)))
93    }
94    fn serialize_i32(self, v: i32) -> Result<Value, SerError> {
95        Ok(Value::Int(i64::from(v)))
96    }
97    fn serialize_i64(self, v: i64) -> Result<Value, SerError> {
98        Ok(Value::Int(v))
99    }
100    fn serialize_u8(self, v: u8) -> Result<Value, SerError> {
101        Ok(Value::Int(i64::from(v)))
102    }
103    fn serialize_u16(self, v: u16) -> Result<Value, SerError> {
104        Ok(Value::Int(i64::from(v)))
105    }
106    fn serialize_u32(self, v: u32) -> Result<Value, SerError> {
107        Ok(Value::Int(i64::from(v)))
108    }
109    fn serialize_u64(self, v: u64) -> Result<Value, SerError> {
110        let i = i64::try_from(v).map_err(|_| {
111            <SerError as ser::Error>::custom(format!("u64 value {v} exceeds i64::MAX"))
112        })?;
113        Ok(Value::Int(i))
114    }
115    fn serialize_f32(self, v: f32) -> Result<Value, SerError> {
116        Ok(Value::Float(f64::from(v)))
117    }
118    fn serialize_f64(self, v: f64) -> Result<Value, SerError> {
119        Ok(Value::Float(v))
120    }
121    fn serialize_char(self, v: char) -> Result<Value, SerError> {
122        Ok(Value::Str(v.to_string()))
123    }
124    fn serialize_str(self, v: &str) -> Result<Value, SerError> {
125        Ok(Value::Str(v.to_string()))
126    }
127    fn serialize_bytes(self, _v: &[u8]) -> Result<Value, SerError> {
128        Err(SerError("byte arrays are not supported".into()))
129    }
130
131    fn serialize_none(self) -> Result<Value, SerError> {
132        // Map to the template engine's `Value::None` for `option(T)`.
133        Ok(Value::None)
134    }
135    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Value, SerError> {
136        value.serialize(self)
137    }
138    fn serialize_unit(self) -> Result<Value, SerError> {
139        Ok(Value::Str(String::new()))
140    }
141    fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, SerError> {
142        Ok(Value::Str(String::new()))
143    }
144    fn serialize_unit_variant(
145        self,
146        _name: &'static str,
147        _idx: u32,
148        variant: &'static str,
149    ) -> Result<Value, SerError> {
150        Ok(Value::Str(variant.to_string()))
151    }
152
153    fn serialize_newtype_struct<T: ?Sized + Serialize>(
154        self,
155        _name: &'static str,
156        value: &T,
157    ) -> Result<Value, SerError> {
158        value.serialize(self)
159    }
160
161    fn serialize_newtype_variant<T: ?Sized + Serialize>(
162        self,
163        _name: &'static str,
164        _idx: u32,
165        variant: &'static str,
166        value: &T,
167    ) -> Result<Value, SerError> {
168        let inner = value.serialize(ValueSerializer)?;
169        Ok(Value::Struct(Arc::new(HashMap::from([(
170            variant.to_string(),
171            inner,
172        )]))))
173    }
174
175    fn serialize_seq(self, len: Option<usize>) -> Result<SeqBuilder, SerError> {
176        Ok(SeqBuilder(Vec::with_capacity(len.unwrap_or(0))))
177    }
178    fn serialize_tuple(self, len: usize) -> Result<SeqBuilder, SerError> {
179        Ok(SeqBuilder(Vec::with_capacity(len)))
180    }
181    fn serialize_tuple_struct(
182        self,
183        _name: &'static str,
184        len: usize,
185    ) -> Result<SeqBuilder, SerError> {
186        Ok(SeqBuilder(Vec::with_capacity(len)))
187    }
188    fn serialize_tuple_variant(
189        self,
190        _name: &'static str,
191        _idx: u32,
192        _variant: &'static str,
193        len: usize,
194    ) -> Result<SeqBuilder, SerError> {
195        Ok(SeqBuilder(Vec::with_capacity(len)))
196    }
197
198    fn serialize_map(self, len: Option<usize>) -> Result<MapBuilder, SerError> {
199        Ok(MapBuilder {
200            map: HashMap::with_capacity(len.unwrap_or(0)),
201            pending_key: None,
202        })
203    }
204    fn serialize_struct(self, _name: &'static str, len: usize) -> Result<MapBuilder, SerError> {
205        Ok(MapBuilder {
206            map: HashMap::with_capacity(len),
207            pending_key: None,
208        })
209    }
210    fn serialize_struct_variant(
211        self,
212        _name: &'static str,
213        _idx: u32,
214        variant: &'static str,
215        len: usize,
216    ) -> Result<MapBuilder, SerError> {
217        let mut map = HashMap::with_capacity(len + 1); // +1 for the tag key
218        map.insert(
219            crate::consts::ENUM_TAG_KEY.to_string(),
220            Value::Str(variant.to_string()),
221        );
222        Ok(MapBuilder {
223            map,
224            pending_key: None,
225        })
226    }
227}
228
229// ---------------------------------------------------------------------------
230// Sequence builder
231// ---------------------------------------------------------------------------
232
233struct SeqBuilder(Vec<Value>);
234
235impl ser::SerializeSeq for SeqBuilder {
236    type Ok = Value;
237    type Error = SerError;
238    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), SerError> {
239        self.0.push(value.serialize(ValueSerializer)?);
240        Ok(())
241    }
242    fn end(self) -> Result<Value, SerError> {
243        Ok(Value::List(Arc::new(self.0)))
244    }
245}
246
247impl ser::SerializeTuple for SeqBuilder {
248    type Ok = Value;
249    type Error = SerError;
250    fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), SerError> {
251        ser::SerializeSeq::serialize_element(self, value)
252    }
253    fn end(self) -> Result<Value, SerError> {
254        ser::SerializeSeq::end(self)
255    }
256}
257
258impl ser::SerializeTupleStruct for SeqBuilder {
259    type Ok = Value;
260    type Error = SerError;
261    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), SerError> {
262        ser::SerializeSeq::serialize_element(self, value)
263    }
264    fn end(self) -> Result<Value, SerError> {
265        ser::SerializeSeq::end(self)
266    }
267}
268
269impl ser::SerializeTupleVariant for SeqBuilder {
270    type Ok = Value;
271    type Error = SerError;
272    fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), SerError> {
273        ser::SerializeSeq::serialize_element(self, value)
274    }
275    fn end(self) -> Result<Value, SerError> {
276        ser::SerializeSeq::end(self)
277    }
278}
279
280// ---------------------------------------------------------------------------
281// Map/struct builder
282// ---------------------------------------------------------------------------
283
284struct MapBuilder {
285    map: HashMap<String, Value>,
286    pending_key: Option<String>,
287}
288
289impl ser::SerializeMap for MapBuilder {
290    type Ok = Value;
291    type Error = SerError;
292    fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), SerError> {
293        let key_val = key.serialize(ValueSerializer)?;
294        match key_val {
295            Value::Str(s) => {
296                self.pending_key = Some(s);
297                Ok(())
298            }
299            Value::Int(i) => {
300                self.pending_key = Some(i.to_string());
301                Ok(())
302            }
303            other => Err(SerError(format!(
304                "map keys must be strings or integers, got {}",
305                other.type_name()
306            ))),
307        }
308    }
309    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), SerError> {
310        let key = self
311            .pending_key
312            .take()
313            .ok_or_else(|| SerError("serialize_value called without serialize_key".into()))?;
314        self.map.insert(key, value.serialize(ValueSerializer)?);
315        Ok(())
316    }
317    fn end(self) -> Result<Value, SerError> {
318        Ok(Value::Struct(Arc::new(self.map)))
319    }
320}
321
322impl ser::SerializeStruct for MapBuilder {
323    type Ok = Value;
324    type Error = SerError;
325    fn serialize_field<T: ?Sized + Serialize>(
326        &mut self,
327        key: &'static str,
328        value: &T,
329    ) -> Result<(), SerError> {
330        self.map
331            .insert(key.to_string(), value.serialize(ValueSerializer)?);
332        Ok(())
333    }
334    fn end(self) -> Result<Value, SerError> {
335        Ok(Value::Struct(Arc::new(self.map)))
336    }
337}
338
339impl ser::SerializeStructVariant for MapBuilder {
340    type Ok = Value;
341    type Error = SerError;
342    fn serialize_field<T: ?Sized + Serialize>(
343        &mut self,
344        key: &'static str,
345        value: &T,
346    ) -> Result<(), SerError> {
347        ser::SerializeStruct::serialize_field(self, key, value)
348    }
349    fn end(self) -> Result<Value, SerError> {
350        ser::SerializeStruct::end(self)
351    }
352}
353
354// ---------------------------------------------------------------------------
355// Deserializer implementation: Value → T
356// ---------------------------------------------------------------------------
357
358use serde::de::{self, Deserialize};
359
360/// Error type for Value-to-Deserialize conversion.
361#[derive(Debug)]
362pub struct DeError(String);
363
364impl fmt::Display for DeError {
365    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366        f.write_str(&self.0)
367    }
368}
369
370impl core::error::Error for DeError {}
371
372impl de::Error for DeError {
373    fn custom<T: fmt::Display>(msg: T) -> Self {
374        Self(msg.to_string())
375    }
376}
377
378/// Convert a [`Value`] back into any `Deserialize` type.
379///
380/// This is the inverse of [`to_value`]. Enums are supported:
381/// - `Value::Str("Variant")` deserializes as a unit variant.
382/// - `Value::Struct({"__kind__": "Variant", ...})` deserializes as a struct variant.
383///
384/// # Errors
385///
386/// Returns an error if the value shape doesn't match the target type.
387///
388/// # Examples
389///
390/// ```
391/// use md_tmpl_core::Value;
392/// use serde::Deserialize;
393///
394/// #[derive(Deserialize, Debug, PartialEq)]
395/// struct Agent {
396///     name: String,
397///     score: i64,
398/// }
399///
400/// let val = Value::new_struct([
401///     ("name", Value::Str("Alice".into())),
402///     ("score", Value::Int(95)),
403/// ]);
404/// let agent: Agent = md_tmpl_core::from_value(&val).unwrap();
405/// assert_eq!(
406///     agent,
407///     Agent {
408///         name: "Alice".into(),
409///         score: 95
410///     }
411/// );
412/// ```
413pub fn from_value<'de, T: Deserialize<'de>>(value: &'de Value) -> Result<T, DeError> {
414    T::deserialize(ValueDeserializer(value))
415}
416
417struct ValueDeserializer<'de>(&'de Value);
418
419impl<'de> de::Deserializer<'de> for ValueDeserializer<'de> {
420    type Error = DeError;
421
422    fn deserialize_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
423        match self.0 {
424            Value::Str(s) => visitor.visit_borrowed_str(s),
425            Value::Int(i) => visitor.visit_i64(*i),
426            Value::Float(f) => visitor.visit_f64(*f),
427            Value::Bool(b) => visitor.visit_bool(*b),
428            Value::List(v) => visitor.visit_seq(SeqDeserializer::new(v)),
429            Value::Struct(m) => visitor.visit_map(MapDeserializer::new(m)),
430            Value::Tmpl(_) => Err(DeError(
431                "cannot deserialize a Tmpl value — templates are not data".into(),
432            )),
433            Value::None => visitor.visit_none(),
434        }
435    }
436
437    fn deserialize_bool<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
438        match self.0 {
439            Value::Bool(b) => visitor.visit_bool(*b),
440            other => Err(DeError(format!("expected bool, got {}", other.type_name()))),
441        }
442    }
443
444    fn deserialize_i64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
445        match self.0 {
446            Value::Int(i) => visitor.visit_i64(*i),
447            other => Err(DeError(format!("expected int, got {}", other.type_name()))),
448        }
449    }
450
451    fn deserialize_f64<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
452        match self.0 {
453            Value::Float(f) => visitor.visit_f64(*f),
454            other => Err(DeError(format!(
455                "expected float, got {}",
456                other.type_name()
457            ))),
458        }
459    }
460
461    fn deserialize_str<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
462        match self.0 {
463            Value::Str(s) => visitor.visit_borrowed_str(s),
464            other => Err(DeError(format!("expected str, got {}", other.type_name()))),
465        }
466    }
467
468    fn deserialize_string<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
469        self.deserialize_str(visitor)
470    }
471
472    fn deserialize_seq<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
473        match self.0 {
474            Value::List(v) => visitor.visit_seq(SeqDeserializer::new(v)),
475            other => Err(DeError(format!("expected list, got {}", other.type_name()))),
476        }
477    }
478
479    fn deserialize_map<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
480        match self.0 {
481            Value::Struct(m) => visitor.visit_map(MapDeserializer::new(m)),
482            other => Err(DeError(format!("expected dict, got {}", other.type_name()))),
483        }
484    }
485
486    fn deserialize_struct<V: de::Visitor<'de>>(
487        self,
488        _name: &'static str,
489        _fields: &'static [&'static str],
490        visitor: V,
491    ) -> Result<V::Value, DeError> {
492        self.deserialize_map(visitor)
493    }
494
495    fn deserialize_enum<V: de::Visitor<'de>>(
496        self,
497        _name: &'static str,
498        _variants: &'static [&'static str],
499        visitor: V,
500    ) -> Result<V::Value, DeError> {
501        match self.0 {
502            // Unit variant: Value::Str("Variant")
503            Value::Str(s) => visitor.visit_enum(EnumDeserializer::Unit(s)),
504            // Struct variant: Value::Struct({"__kind__": "Variant", ...fields})
505            Value::Struct(m) => {
506                let tag_key = crate::consts::ENUM_TAG_KEY;
507                let tag = match m.get(tag_key) {
508                    Some(Value::Str(s)) => s.as_str(),
509                    _ => {
510                        return Err(DeError(format!(
511                            "enum dict missing '{tag_key}' string field"
512                        )));
513                    }
514                };
515                visitor.visit_enum(EnumDeserializer::Struct { tag, fields: m })
516            }
517            other => Err(DeError(format!(
518                "expected str or dict for enum, got {}",
519                other.type_name()
520            ))),
521        }
522    }
523
524    fn deserialize_option<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
525        match self.0 {
526            Value::None => visitor.visit_none(),
527            // Legacy: template `None` variant string or empty string → Rust None.
528            Value::Str(s) if s.is_empty() || s == crate::consts::OPTION_NONE => {
529                visitor.visit_none()
530            }
531            _ => visitor.visit_some(self),
532        }
533    }
534
535    fn deserialize_newtype_struct<V: de::Visitor<'de>>(
536        self,
537        _name: &'static str,
538        visitor: V,
539    ) -> Result<V::Value, DeError> {
540        visitor.visit_newtype_struct(self)
541    }
542
543    fn deserialize_unit<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
544        visitor.visit_unit()
545    }
546
547    fn deserialize_unit_struct<V: de::Visitor<'de>>(
548        self,
549        _name: &'static str,
550        visitor: V,
551    ) -> Result<V::Value, DeError> {
552        visitor.visit_unit()
553    }
554
555    fn deserialize_tuple<V: de::Visitor<'de>>(
556        self,
557        _len: usize,
558        visitor: V,
559    ) -> Result<V::Value, DeError> {
560        self.deserialize_seq(visitor)
561    }
562
563    fn deserialize_tuple_struct<V: de::Visitor<'de>>(
564        self,
565        _name: &'static str,
566        _len: usize,
567        visitor: V,
568    ) -> Result<V::Value, DeError> {
569        self.deserialize_seq(visitor)
570    }
571
572    fn deserialize_identifier<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
573        self.deserialize_str(visitor)
574    }
575
576    fn deserialize_ignored_any<V: de::Visitor<'de>>(self, visitor: V) -> Result<V::Value, DeError> {
577        visitor.visit_unit()
578    }
579
580    // Forward numeric widths to i64/f64
581    serde::forward_to_deserialize_any! { i8 i16 i32 u8 u16 u32 u64 f32 char bytes byte_buf }
582}
583
584// -- Sequence deserializer --
585
586struct SeqDeserializer<'de> {
587    iter: core::slice::Iter<'de, Value>,
588}
589
590impl<'de> SeqDeserializer<'de> {
591    fn new(v: &'de [Value]) -> Self {
592        Self { iter: v.iter() }
593    }
594}
595
596impl<'de> de::SeqAccess<'de> for SeqDeserializer<'de> {
597    type Error = DeError;
598    fn next_element_seed<T: de::DeserializeSeed<'de>>(
599        &mut self,
600        seed: T,
601    ) -> Result<Option<T::Value>, DeError> {
602        match self.iter.next() {
603            Some(val) => seed.deserialize(ValueDeserializer(val)).map(Some),
604            None => Ok(None),
605        }
606    }
607}
608
609// -- Map deserializer --
610
611struct MapDeserializer<'de> {
612    iter: crate::compat::hash_map::Iter<'de, String, Value>,
613    current_value: Option<&'de Value>,
614}
615
616impl<'de> MapDeserializer<'de> {
617    fn new(m: &'de HashMap<String, Value>) -> Self {
618        Self {
619            iter: m.iter(),
620            current_value: None,
621        }
622    }
623}
624
625impl<'de> de::MapAccess<'de> for MapDeserializer<'de> {
626    type Error = DeError;
627
628    fn next_key_seed<K: de::DeserializeSeed<'de>>(
629        &mut self,
630        seed: K,
631    ) -> Result<Option<K::Value>, DeError> {
632        match self.iter.next() {
633            Some((key, val)) => {
634                self.current_value = Some(val);
635                seed.deserialize(de::value::BorrowedStrDeserializer::new(key.as_str()))
636                    .map(Some)
637            }
638            None => Ok(None),
639        }
640    }
641
642    fn next_value_seed<V: de::DeserializeSeed<'de>>(
643        &mut self,
644        seed: V,
645    ) -> Result<V::Value, DeError> {
646        let val = self
647            .current_value
648            .take()
649            .ok_or_else(|| DeError("map value without key".into()))?;
650        seed.deserialize(ValueDeserializer(val))
651    }
652}
653
654// -- Enum deserializer --
655
656enum EnumDeserializer<'de> {
657    Unit(&'de str),
658    Struct {
659        tag: &'de str,
660        fields: &'de HashMap<String, Value>,
661    },
662}
663
664impl<'de> de::EnumAccess<'de> for EnumDeserializer<'de> {
665    type Error = DeError;
666    type Variant = VariantDeserializer<'de>;
667
668    fn variant_seed<V: de::DeserializeSeed<'de>>(
669        self,
670        seed: V,
671    ) -> Result<(V::Value, Self::Variant), DeError> {
672        match self {
673            Self::Unit(tag) => {
674                let variant = seed.deserialize(de::value::BorrowedStrDeserializer::new(tag))?;
675                Ok((variant, VariantDeserializer::Unit))
676            }
677            Self::Struct { tag, fields } => {
678                let variant = seed.deserialize(de::value::BorrowedStrDeserializer::new(tag))?;
679                Ok((variant, VariantDeserializer::Struct(fields)))
680            }
681        }
682    }
683}
684
685enum VariantDeserializer<'de> {
686    Unit,
687    Struct(&'de HashMap<String, Value>),
688}
689
690impl<'de> de::VariantAccess<'de> for VariantDeserializer<'de> {
691    type Error = DeError;
692
693    fn unit_variant(self) -> Result<(), DeError> {
694        Ok(())
695    }
696
697    fn newtype_variant_seed<T: de::DeserializeSeed<'de>>(
698        self,
699        _seed: T,
700    ) -> Result<T::Value, DeError> {
701        Err(DeError(
702            "newtype variants not supported in from_value".into(),
703        ))
704    }
705
706    fn tuple_variant<V: de::Visitor<'de>>(
707        self,
708        _len: usize,
709        _visitor: V,
710    ) -> Result<V::Value, DeError> {
711        Err(DeError("tuple variants not supported in from_value".into()))
712    }
713
714    fn struct_variant<V: de::Visitor<'de>>(
715        self,
716        _fields: &'static [&'static str],
717        visitor: V,
718    ) -> Result<V::Value, DeError> {
719        match self {
720            Self::Struct(fields) => {
721                // Use a filtering iterator that skips the ENUM_TAG_KEY key
722                visitor.visit_map(FilteredMapDeserializer::new(fields))
723            }
724            Self::Unit => Err(DeError("expected struct variant, got unit".into())),
725        }
726    }
727}
728
729// -- Filtered map deserializer (skips ENUM_TAG_KEY for struct variants) --
730
731struct FilteredMapDeserializer<'de> {
732    iter: crate::compat::hash_map::Iter<'de, String, Value>,
733    current_value: Option<&'de Value>,
734}
735
736impl<'de> FilteredMapDeserializer<'de> {
737    fn new(m: &'de HashMap<String, Value>) -> Self {
738        Self {
739            iter: m.iter(),
740            current_value: None,
741        }
742    }
743}
744
745impl<'de> de::MapAccess<'de> for FilteredMapDeserializer<'de> {
746    type Error = DeError;
747
748    fn next_key_seed<K: de::DeserializeSeed<'de>>(
749        &mut self,
750        seed: K,
751    ) -> Result<Option<K::Value>, DeError> {
752        loop {
753            match self.iter.next() {
754                Some((key, val)) => {
755                    if key == crate::consts::ENUM_TAG_KEY {
756                        continue; // skip "tag"
757                    }
758                    self.current_value = Some(val);
759                    return seed
760                        .deserialize(de::value::BorrowedStrDeserializer::new(key.as_str()))
761                        .map(Some);
762                }
763                None => return Ok(None),
764            }
765        }
766    }
767
768    fn next_value_seed<V: de::DeserializeSeed<'de>>(
769        &mut self,
770        seed: V,
771    ) -> Result<V::Value, DeError> {
772        let val = self
773            .current_value
774            .take()
775            .ok_or_else(|| DeError("map value without key".into()))?;
776        seed.deserialize(ValueDeserializer(val))
777    }
778}
779
780// ---------------------------------------------------------------------------
781// Deserializer implementation: D → Value
782// ---------------------------------------------------------------------------
783
784impl<'de> serde::Deserialize<'de> for Value {
785    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
786    where
787        D: serde::Deserializer<'de>,
788    {
789        struct ValueVisitor;
790        impl<'de> serde::de::Visitor<'de> for ValueVisitor {
791            type Value = Value;
792            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
793                formatter.write_str("any valid template value")
794            }
795            fn visit_bool<E: serde::de::Error>(self, v: bool) -> Result<Self::Value, E> {
796                Ok(Value::Bool(v))
797            }
798            fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<Self::Value, E> {
799                Ok(Value::Int(v))
800            }
801            fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<Self::Value, E> {
802                Ok(Value::Int(v.try_into().map_err(serde::de::Error::custom)?))
803            }
804            fn visit_f64<E: serde::de::Error>(self, v: f64) -> Result<Self::Value, E> {
805                Ok(Value::Float(v))
806            }
807            fn visit_str<E: serde::de::Error>(self, v: &str) -> Result<Self::Value, E> {
808                Ok(Value::Str(v.into()))
809            }
810            fn visit_string<E: serde::de::Error>(self, v: String) -> Result<Self::Value, E> {
811                Ok(Value::Str(v))
812            }
813            fn visit_seq<A: serde::de::SeqAccess<'de>>(
814                self,
815                mut seq: A,
816            ) -> Result<Self::Value, A::Error> {
817                let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
818                while let Some(elem) = seq.next_element()? {
819                    vec.push(elem);
820                }
821                Ok(Value::List(Arc::new(vec)))
822            }
823            fn visit_map<A: serde::de::MapAccess<'de>>(
824                self,
825                mut map: A,
826            ) -> Result<Self::Value, A::Error> {
827                let mut hashmap =
828                    crate::compat::HashMap::with_capacity(map.size_hint().unwrap_or(0));
829                while let Some((key, value)) = map.next_entry::<String, Value>()? {
830                    hashmap.insert(key, value);
831                }
832                Ok(Value::Struct(Arc::new(hashmap)))
833            }
834            fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
835                // null / unit → template `Value::None` for `option(T)`.
836                Ok(Value::None)
837            }
838            fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
839                // serde `None` → template `Value::None` for `option(T)`.
840                Ok(Value::None)
841            }
842        }
843        deserializer.deserialize_any(ValueVisitor)
844    }
845}