serde_reflection/
json_converter.rs

1// Copyright (c) Zefchain Labs, Inc. and its affiliates
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! Dynamic conversion to JSON values
5
6use crate::{ContainerFormat, Format, Named, Registry, VariantFormat};
7use serde::de::{DeserializeSeed, MapAccess, SeqAccess, Visitor};
8use serde::ser::{
9    SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, SerializeTuple,
10    SerializeTupleStruct, SerializeTupleVariant,
11};
12use serde::{Deserialize, Deserializer, Serialize, Serializer};
13use serde_json::{Number, Value};
14use std::collections::BTreeMap;
15
16/// A deserialization context to create a JSON value from a serialized object in a dynamic
17/// format.
18pub struct DeserializationContext<'a, E> {
19    /// The format of the main value.
20    pub format: Format,
21    /// The registry of container formats.
22    pub registry: &'a Registry,
23    /// The environment containing external parsers.
24    pub environment: &'a E,
25}
26
27use once_cell::sync::Lazy;
28use std::{collections::HashSet, sync::Mutex};
29
30static GLOBAL_STRING_SET: Lazy<Mutex<HashSet<&'static str>>> =
31    Lazy::new(|| Mutex::new(HashSet::new()));
32
33static GLOBAL_FIELDS_SET: Lazy<Mutex<HashSet<&'static [&'static str]>>> =
34    Lazy::new(|| Mutex::new(HashSet::new()));
35
36/// The requirement for an `environment` that manages a symbol table.
37pub trait SymbolTableEnvironment {
38    fn get_static_name(&self, name: &str) -> &'static str {
39        let mut set = GLOBAL_STRING_SET.lock().unwrap();
40        // TODO: use https://github.com/rust-lang/rust/issues/60896 when available
41        if let Some(value) = set.get(name) {
42            value
43        } else {
44            set.insert(name.to_string().leak());
45            set.get(name).unwrap()
46        }
47    }
48
49    fn get_static_fields<'a>(
50        &self,
51        fields: impl IntoIterator<Item = &'a str>,
52    ) -> &'static [&'static str] {
53        let fields = fields
54            .into_iter()
55            .map(|name| self.get_static_name(name))
56            .collect::<Vec<_>>();
57        let mut set = GLOBAL_FIELDS_SET.lock().unwrap();
58        // TODO: use https://github.com/rust-lang/rust/issues/60896 when available
59        if let Some(value) = set.get(fields.as_slice()) {
60            value
61        } else {
62            set.insert(fields.to_vec().leak());
63            set.get(fields.as_slice()).unwrap()
64        }
65    }
66}
67
68/// The requirement for the `environment` objects to help with Deserialize.
69pub trait DeserializationEnvironment<'de>: SymbolTableEnvironment {
70    /// Deserialize a value of an external type `name`.
71    fn deserialize<D>(&self, name: String, deserializer: D) -> Result<Value, String>
72    where
73        D: Deserializer<'de>;
74}
75
76pub struct EmptyEnvironment;
77
78impl SymbolTableEnvironment for EmptyEnvironment {}
79
80impl<'de> DeserializationEnvironment<'de> for EmptyEnvironment {
81    fn deserialize<D>(&self, name: String, _deserializer: D) -> Result<Value, String>
82    where
83        D: Deserializer<'de>,
84    {
85        Err(format!("No external definition available for {name}"))
86    }
87}
88
89impl<'a, 'de, E> DeserializeSeed<'de> for DeserializationContext<'a, E>
90where
91    E: DeserializationEnvironment<'de>,
92{
93    type Value = Value;
94
95    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
96    where
97        D: Deserializer<'de>,
98    {
99        use Format::*;
100
101        match self.format {
102            Variable(_) => Err(<D::Error as serde::de::Error>::custom(
103                "Required formats cannot contain variables",
104            )),
105            TypeName(name) => {
106                if let Some(container_format) = self.registry.get(&name) {
107                    // Process the container format by deserializing according to its structure
108                    deserialize_container_format(
109                        &name,
110                        container_format,
111                        self.registry,
112                        self.environment,
113                        deserializer,
114                    )
115                } else {
116                    Ok(self
117                        .environment
118                        .deserialize(name, deserializer)
119                        .map_err(<D::Error as serde::de::Error>::custom)?)
120                }
121            }
122            Unit => Ok(Value::Null),
123            Bool => {
124                let value = bool::deserialize(deserializer)?;
125                Ok(Value::Bool(value))
126            }
127            I8 => {
128                let value = i8::deserialize(deserializer)?;
129                Ok(Value::Number(Number::from(value)))
130            }
131            I16 => {
132                let value = i16::deserialize(deserializer)?;
133                Ok(Value::Number(Number::from(value)))
134            }
135            I32 => {
136                let value = i32::deserialize(deserializer)?;
137                Ok(Value::Number(Number::from(value)))
138            }
139            I64 => {
140                let value = i64::deserialize(deserializer)?;
141                Ok(Value::Number(Number::from(value)))
142            }
143            I128 => {
144                let value = i128::deserialize(deserializer)?;
145                // i128 is too large for JSON Number, so we convert to i64 if possible
146                // or use a string representation
147                if let Ok(small_value) = i64::try_from(value) {
148                    Ok(Value::Number(Number::from(small_value)))
149                } else {
150                    Ok(Value::String(value.to_string()))
151                }
152            }
153            U8 => {
154                let value = u8::deserialize(deserializer)?;
155                Ok(Value::Number(Number::from(value)))
156            }
157            U16 => {
158                let value = u16::deserialize(deserializer)?;
159                Ok(Value::Number(Number::from(value)))
160            }
161            U32 => {
162                let value = u32::deserialize(deserializer)?;
163                Ok(Value::Number(Number::from(value)))
164            }
165            U64 => {
166                let value = u64::deserialize(deserializer)?;
167                Ok(Value::Number(Number::from(value)))
168            }
169            U128 => {
170                let value = u128::deserialize(deserializer)?;
171                // u128 is too large for JSON Number, so we convert to u64 if possible
172                // or use a string representation
173                if let Ok(small_value) = u64::try_from(value) {
174                    Ok(Value::Number(Number::from(small_value)))
175                } else {
176                    Ok(Value::String(value.to_string()))
177                }
178            }
179            F32 => {
180                let value = f32::deserialize(deserializer)?;
181                Number::from_f64(value as f64)
182                    .map(Value::Number)
183                    .ok_or_else(|| <D::Error as serde::de::Error>::custom("Invalid f32 value"))
184            }
185            F64 => {
186                let value = f64::deserialize(deserializer)?;
187                Number::from_f64(value)
188                    .map(Value::Number)
189                    .ok_or_else(|| <D::Error as serde::de::Error>::custom("Invalid f64 value"))
190            }
191            Char => {
192                let value = char::deserialize(deserializer)?;
193                Ok(Value::String(value.to_string()))
194            }
195            Str => {
196                let value = String::deserialize(deserializer)?;
197                Ok(Value::String(value))
198            }
199            Bytes => {
200                let value = Vec::<u8>::deserialize(deserializer)?;
201                Ok(Value::Array(
202                    value
203                        .into_iter()
204                        .map(|b| Value::Number(Number::from(b)))
205                        .collect(),
206                ))
207            }
208            Option(format) => {
209                let visitor = OptionVisitor {
210                    format: *format,
211                    registry: self.registry,
212                    environment: self.environment,
213                };
214                deserializer.deserialize_option(visitor)
215            }
216            Seq(format) => {
217                let visitor = SeqVisitor {
218                    format: *format,
219                    registry: self.registry,
220                    environment: self.environment,
221                };
222                deserializer.deserialize_seq(visitor)
223            }
224            Map { key, value } => {
225                let visitor = MapVisitor {
226                    key_format: *key,
227                    value_format: *value,
228                    registry: self.registry,
229                    environment: self.environment,
230                };
231                deserializer.deserialize_map(visitor)
232            }
233            Tuple(formats) => {
234                let visitor = TupleVisitor {
235                    formats,
236                    registry: self.registry,
237                    environment: self.environment,
238                };
239                deserializer.deserialize_tuple(visitor.formats.len(), visitor)
240            }
241            TupleArray { content, size } => {
242                let visitor = TupleArrayVisitor {
243                    format: *content,
244                    size,
245                    registry: self.registry,
246                    environment: self.environment,
247                };
248                deserializer.deserialize_tuple(visitor.size, visitor)
249            }
250        }
251    }
252}
253
254struct OptionVisitor<'a, E> {
255    format: Format,
256    registry: &'a Registry,
257    environment: &'a E,
258}
259
260impl<'a, 'de, E> Visitor<'de> for OptionVisitor<'a, E>
261where
262    E: DeserializationEnvironment<'de>,
263{
264    type Value = Value;
265
266    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
267        formatter.write_str("an optional value")
268    }
269
270    fn visit_none<Err>(self) -> Result<Self::Value, Err>
271    where
272        Err: serde::de::Error,
273    {
274        Ok(Value::Null)
275    }
276
277    fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
278    where
279        D: Deserializer<'de>,
280    {
281        let context = DeserializationContext {
282            format: self.format,
283            registry: self.registry,
284            environment: self.environment,
285        };
286        context.deserialize(deserializer)
287    }
288
289    fn visit_unit<Err>(self) -> Result<Self::Value, Err>
290    where
291        Err: serde::de::Error,
292    {
293        Ok(Value::Null)
294    }
295}
296
297struct SeqVisitor<'a, E> {
298    format: Format,
299    registry: &'a Registry,
300    environment: &'a E,
301}
302
303impl<'a, 'de, E> Visitor<'de> for SeqVisitor<'a, E>
304where
305    E: DeserializationEnvironment<'de>,
306{
307    type Value = Value;
308
309    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
310        formatter.write_str("a sequence")
311    }
312
313    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
314    where
315        A: SeqAccess<'de>,
316    {
317        let mut values = Vec::new();
318        while let Some(value) = seq.next_element_seed(DeserializationContext {
319            format: self.format.clone(),
320            registry: self.registry,
321            environment: self.environment,
322        })? {
323            values.push(value);
324        }
325        Ok(Value::Array(values))
326    }
327}
328
329struct MapVisitor<'a, E> {
330    key_format: Format,
331    value_format: Format,
332    registry: &'a Registry,
333    environment: &'a E,
334}
335
336impl<'a, 'de, E> Visitor<'de> for MapVisitor<'a, E>
337where
338    E: DeserializationEnvironment<'de>,
339{
340    type Value = Value;
341
342    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
343        formatter.write_str("a map")
344    }
345
346    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
347    where
348        A: MapAccess<'de>,
349    {
350        let mut object = serde_json::Map::new();
351        while let Some((key, value)) = map.next_entry_seed(
352            DeserializationContext {
353                format: self.key_format.clone(),
354                registry: self.registry,
355                environment: self.environment,
356            },
357            DeserializationContext {
358                format: self.value_format.clone(),
359                registry: self.registry,
360                environment: self.environment,
361            },
362        )? {
363            // Convert the key Value to a String
364            let key_string = match key {
365                Value::String(s) => s,
366                Value::Number(n) => n.to_string(),
367                Value::Bool(b) => b.to_string(),
368                _ => {
369                    return Err(serde::de::Error::custom(
370                        "Map keys must be strings, numbers, or booleans",
371                    ))
372                }
373            };
374            object.insert(key_string, value);
375        }
376        Ok(Value::Object(object))
377    }
378}
379
380struct TupleVisitor<'a, E> {
381    formats: Vec<Format>,
382    registry: &'a Registry,
383    environment: &'a E,
384}
385
386impl<'a, 'de, E> Visitor<'de> for TupleVisitor<'a, E>
387where
388    E: DeserializationEnvironment<'de>,
389{
390    type Value = Value;
391
392    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
393        formatter.write_str("a tuple")
394    }
395
396    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
397    where
398        A: SeqAccess<'de>,
399    {
400        let mut values = Vec::new();
401        for format in self.formats {
402            match seq.next_element_seed(DeserializationContext {
403                format,
404                registry: self.registry,
405                environment: self.environment,
406            })? {
407                Some(value) => values.push(value),
408                None => {
409                    return Err(serde::de::Error::custom(
410                        "Tuple has fewer elements than expected",
411                    ))
412                }
413            }
414        }
415        Ok(Value::Array(values))
416    }
417}
418
419struct TupleArrayVisitor<'a, E> {
420    format: Format,
421    size: usize,
422    registry: &'a Registry,
423    environment: &'a E,
424}
425
426impl<'a, 'de, E> Visitor<'de> for TupleArrayVisitor<'a, E>
427where
428    E: DeserializationEnvironment<'de>,
429{
430    type Value = Value;
431
432    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
433        formatter.write_str("a tuple array")
434    }
435
436    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
437    where
438        A: SeqAccess<'de>,
439    {
440        let mut values = Vec::new();
441        for _ in 0..self.size {
442            match seq.next_element_seed(DeserializationContext {
443                format: self.format.clone(),
444                registry: self.registry,
445                environment: self.environment,
446            })? {
447                Some(value) => values.push(value),
448                None => {
449                    return Err(serde::de::Error::custom(
450                        "Tuple array has fewer elements than expected",
451                    ))
452                }
453            }
454        }
455        Ok(Value::Array(values))
456    }
457}
458
459// Helper function to deserialize a container format
460fn deserialize_container_format<'a, 'de, E, D>(
461    name: &str,
462    container_format: &'a ContainerFormat,
463    registry: &'a Registry,
464    environment: &'a E,
465    deserializer: D,
466) -> Result<Value, D::Error>
467where
468    E: DeserializationEnvironment<'de>,
469    D: Deserializer<'de>,
470{
471    use ContainerFormat::*;
472
473    match container_format {
474        UnitStruct => {
475            // Unit structs deserialize as null
476            deserializer.deserialize_unit(UnitStructVisitor)
477        }
478        NewTypeStruct(format) => {
479            // NewType structs unwrap to their inner value
480            let name = environment.get_static_name(name);
481            let visitor = NewTypeStructVisitor {
482                format: (**format).clone(),
483                registry,
484                environment,
485            };
486            deserializer.deserialize_newtype_struct(name, visitor)
487        }
488        TupleStruct(formats) => {
489            // Tuple structs deserialize as sequences
490            let visitor = TupleStructVisitor {
491                formats: formats.clone(),
492                registry,
493                environment,
494            };
495            deserializer.deserialize_tuple(formats.len(), visitor)
496        }
497        Struct(fields) => {
498            // Named structs deserialize as maps
499            let name = environment.get_static_name(name);
500            let static_fields =
501                environment.get_static_fields(fields.iter().map(|f| f.name.as_str()));
502            let visitor = StructVisitor {
503                fields: fields.clone(),
504                registry,
505                environment,
506            };
507            deserializer.deserialize_struct(name, static_fields, visitor)
508        }
509        Enum(variants) => {
510            // Enums need special handling
511            let name = environment.get_static_name(name);
512            let static_fields =
513                environment.get_static_fields(variants.iter().map(|(_, v)| v.name.as_str()));
514            let visitor = EnumVisitor {
515                variants: variants.clone(),
516                registry,
517                environment,
518            };
519            deserializer.deserialize_enum(name, static_fields, visitor)
520        }
521    }
522}
523
524struct UnitStructVisitor;
525
526impl<'de> Visitor<'de> for UnitStructVisitor {
527    type Value = Value;
528
529    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
530        formatter.write_str("a unit struct")
531    }
532
533    fn visit_unit<E>(self) -> Result<Self::Value, E>
534    where
535        E: serde::de::Error,
536    {
537        Ok(Value::Null)
538    }
539}
540
541struct NewTypeStructVisitor<'a, E> {
542    format: Format,
543    registry: &'a Registry,
544    environment: &'a E,
545}
546
547impl<'a, 'de, E> Visitor<'de> for NewTypeStructVisitor<'a, E>
548where
549    E: DeserializationEnvironment<'de>,
550{
551    type Value = Value;
552
553    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
554        formatter.write_str("a newtype struct")
555    }
556
557    fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
558    where
559        D: Deserializer<'de>,
560    {
561        let context = DeserializationContext {
562            format: self.format,
563            registry: self.registry,
564            environment: self.environment,
565        };
566        context.deserialize(deserializer)
567    }
568}
569
570struct TupleStructVisitor<'a, E> {
571    formats: Vec<Format>,
572    registry: &'a Registry,
573    environment: &'a E,
574}
575
576impl<'a, 'de, E> Visitor<'de> for TupleStructVisitor<'a, E>
577where
578    E: DeserializationEnvironment<'de>,
579{
580    type Value = Value;
581
582    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
583        formatter.write_str("a tuple struct")
584    }
585
586    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
587    where
588        A: SeqAccess<'de>,
589    {
590        let mut values = Vec::new();
591        for format in self.formats {
592            match seq.next_element_seed(DeserializationContext {
593                format,
594                registry: self.registry,
595                environment: self.environment,
596            })? {
597                Some(value) => values.push(value),
598                None => {
599                    return Err(serde::de::Error::custom(
600                        "Tuple struct has fewer elements than expected",
601                    ))
602                }
603            }
604        }
605        Ok(Value::Array(values))
606    }
607}
608
609struct StructVisitor<'a, E> {
610    fields: Vec<Named<Format>>,
611    registry: &'a Registry,
612    environment: &'a E,
613}
614
615impl<'a, 'de, E> Visitor<'de> for StructVisitor<'a, E>
616where
617    E: DeserializationEnvironment<'de>,
618{
619    type Value = Value;
620
621    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
622        formatter.write_str("a struct")
623    }
624
625    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
626    where
627        A: SeqAccess<'de>,
628    {
629        let mut object = serde_json::Map::new();
630        for field in self.fields {
631            match seq.next_element_seed(DeserializationContext {
632                format: field.value,
633                registry: self.registry,
634                environment: self.environment,
635            })? {
636                Some(value) => {
637                    object.insert(field.name, value);
638                }
639                None => {
640                    return Err(serde::de::Error::custom(
641                        "Struct has fewer fields than expected",
642                    ))
643                }
644            }
645        }
646        Ok(Value::Object(object))
647    }
648
649    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
650    where
651        A: MapAccess<'de>,
652    {
653        let mut object = serde_json::Map::new();
654        let fields_map: BTreeMap<_, _> = self
655            .fields
656            .into_iter()
657            .map(|f| (f.name.clone(), f.value))
658            .collect();
659
660        while let Some(key) = map.next_key::<String>()? {
661            if let Some(format) = fields_map.get(&key) {
662                let value = map.next_value_seed(DeserializationContext {
663                    format: format.clone(),
664                    registry: self.registry,
665                    environment: self.environment,
666                })?;
667                object.insert(key, value);
668            } else {
669                // Skip unknown fields
670                map.next_value::<serde::de::IgnoredAny>()?;
671            }
672        }
673        Ok(Value::Object(object))
674    }
675}
676
677struct EnumVisitor<'a, E> {
678    variants: BTreeMap<u32, Named<VariantFormat>>,
679    registry: &'a Registry,
680    environment: &'a E,
681}
682
683impl<'a, 'de, E> Visitor<'de> for EnumVisitor<'a, E>
684where
685    E: DeserializationEnvironment<'de>,
686{
687    type Value = Value;
688
689    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
690        formatter.write_str("an enum")
691    }
692
693    fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
694    where
695        A: serde::de::EnumAccess<'de>,
696    {
697        // Create a custom deserializer for the variant identifier that can handle
698        // both string names (e.g., JSON) and integer indices (e.g., bincode)
699        let variant_visitor = VariantIdentifierVisitor {
700            variants: &self.variants,
701        };
702
703        let (variant_info, variant_data) = data.variant_seed(variant_visitor)?;
704        let (variant_name, variant_format) = variant_info;
705
706        let variant_value = deserialize_variant_format(
707            &variant_format.value,
708            self.registry,
709            self.environment,
710            variant_data,
711        )?;
712
713        // Return a JSON object with the variant name as key
714        let mut object = serde_json::Map::new();
715        object.insert(variant_name, variant_value);
716        Ok(Value::Object(object))
717    }
718}
719
720struct VariantIdentifierVisitor<'a> {
721    variants: &'a BTreeMap<u32, Named<VariantFormat>>,
722}
723
724impl<'de> serde::de::DeserializeSeed<'de> for VariantIdentifierVisitor<'_> {
725    type Value = (String, Named<VariantFormat>);
726
727    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
728    where
729        D: serde::Deserializer<'de>,
730    {
731        deserializer.deserialize_identifier(self)
732    }
733}
734
735impl<'de> Visitor<'de> for VariantIdentifierVisitor<'_> {
736    type Value = (String, Named<VariantFormat>);
737
738    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
739        formatter.write_str("variant identifier")
740    }
741
742    fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
743    where
744        E: serde::de::Error,
745    {
746        // Handle integer variant indices (e.g., bincode)
747        let variant = self
748            .variants
749            .get(&(value as u32))
750            .ok_or_else(|| serde::de::Error::custom(format!("Unknown variant index: {}", value)))?;
751        Ok((variant.name.clone(), variant.clone()))
752    }
753
754    fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
755    where
756        E: serde::de::Error,
757    {
758        // Handle string variant names (e.g., JSON)
759        let variant = self
760            .variants
761            .values()
762            .find(|v| v.name == value)
763            .ok_or_else(|| serde::de::Error::custom(format!("Unknown variant: {}", value)))?;
764        Ok((variant.name.clone(), variant.clone()))
765    }
766
767    fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
768    where
769        E: serde::de::Error,
770    {
771        // Handle byte string variant names
772        let value_str = std::str::from_utf8(value)
773            .map_err(|_| serde::de::Error::custom("Invalid UTF-8 in variant name"))?;
774        self.visit_str(value_str)
775    }
776}
777
778fn deserialize_variant_format<'a, 'de, E, A>(
779    variant_format: &VariantFormat,
780    registry: &'a Registry,
781    environment: &'a E,
782    variant_data: A,
783) -> Result<Value, A::Error>
784where
785    E: DeserializationEnvironment<'de>,
786    A: serde::de::VariantAccess<'de>,
787{
788    use VariantFormat::*;
789
790    match variant_format {
791        Variable(_) => Err(serde::de::Error::custom(
792            "Variant format cannot contain variables",
793        )),
794        Unit => {
795            variant_data.unit_variant()?;
796            Ok(Value::Null)
797        }
798        NewType(format) => {
799            let context = DeserializationContext {
800                format: (**format).clone(),
801                registry,
802                environment,
803            };
804            variant_data.newtype_variant_seed(context)
805        }
806        Tuple(formats) => {
807            let visitor = TupleVariantVisitor {
808                formats: formats.clone(),
809                registry,
810                environment,
811            };
812            variant_data.tuple_variant(formats.len(), visitor)
813        }
814        Struct(fields) => {
815            let static_fields =
816                environment.get_static_fields(fields.iter().map(|v| v.name.as_str()));
817            let visitor = StructVariantVisitor {
818                fields: fields.clone(),
819                registry,
820                environment,
821            };
822            variant_data.struct_variant(static_fields, visitor)
823        }
824    }
825}
826
827struct TupleVariantVisitor<'a, E> {
828    formats: Vec<Format>,
829    registry: &'a Registry,
830    environment: &'a E,
831}
832
833impl<'a, 'de, E> Visitor<'de> for TupleVariantVisitor<'a, E>
834where
835    E: DeserializationEnvironment<'de>,
836{
837    type Value = Value;
838
839    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
840        formatter.write_str("a tuple variant")
841    }
842
843    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
844    where
845        A: SeqAccess<'de>,
846    {
847        let mut values = Vec::new();
848        for format in self.formats {
849            match seq.next_element_seed(DeserializationContext {
850                format,
851                registry: self.registry,
852                environment: self.environment,
853            })? {
854                Some(value) => values.push(value),
855                None => {
856                    return Err(serde::de::Error::custom(
857                        "Tuple variant has fewer elements than expected",
858                    ))
859                }
860            }
861        }
862        Ok(Value::Array(values))
863    }
864}
865
866struct StructVariantVisitor<'a, E> {
867    fields: Vec<Named<Format>>,
868    registry: &'a Registry,
869    environment: &'a E,
870}
871
872impl<'a, 'de, E> Visitor<'de> for StructVariantVisitor<'a, E>
873where
874    E: DeserializationEnvironment<'de>,
875{
876    type Value = Value;
877
878    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
879        formatter.write_str("a struct variant")
880    }
881
882    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
883    where
884        A: SeqAccess<'de>,
885    {
886        let mut object = serde_json::Map::new();
887        for field in self.fields {
888            match seq.next_element_seed(DeserializationContext {
889                format: field.value,
890                registry: self.registry,
891                environment: self.environment,
892            })? {
893                Some(value) => {
894                    object.insert(field.name, value);
895                }
896                None => {
897                    return Err(serde::de::Error::custom(
898                        "Struct variant has fewer fields than expected",
899                    ))
900                }
901            }
902        }
903        Ok(Value::Object(object))
904    }
905
906    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
907    where
908        A: MapAccess<'de>,
909    {
910        let mut object = serde_json::Map::new();
911        let fields_map: BTreeMap<_, _> = self
912            .fields
913            .into_iter()
914            .map(|f| (f.name.clone(), f.value))
915            .collect();
916
917        while let Some(key) = map.next_key::<String>()? {
918            if let Some(format) = fields_map.get(&key) {
919                let value = map.next_value_seed(DeserializationContext {
920                    format: format.clone(),
921                    registry: self.registry,
922                    environment: self.environment,
923                })?;
924                object.insert(key, value);
925            } else {
926                // Skip unknown fields
927                map.next_value::<serde::de::IgnoredAny>()?;
928            }
929        }
930        Ok(Value::Object(object))
931    }
932}
933
934/// A serialization context to convert a JSON value to a serialized object in a dynamic format.
935pub struct SerializationContext<'a, E> {
936    /// The JSON value to serialize.
937    pub value: &'a Value,
938    /// The format to serialize to.
939    pub format: &'a Format,
940    /// The registry of container formats.
941    pub registry: &'a Registry,
942    /// The environment containing external serializers.
943    pub environment: &'a E,
944}
945
946/// The requirement for the `environment` object for serialization.
947pub trait SerializationEnvironment: SymbolTableEnvironment {
948    /// Serialize a value of an external type `name`.
949    fn serialize<S>(&self, name: &str, value: &Value, serializer: S) -> Result<S::Ok, S::Error>
950    where
951        S: Serializer;
952}
953
954impl SerializationEnvironment for EmptyEnvironment {
955    fn serialize<S>(&self, name: &str, _value: &Value, _serializer: S) -> Result<S::Ok, S::Error>
956    where
957        S: Serializer,
958    {
959        Err(serde::ser::Error::custom(format!(
960            "No external serializer available for {name}"
961        )))
962    }
963}
964
965impl<'a, E> Serialize for SerializationContext<'a, E>
966where
967    E: SerializationEnvironment,
968{
969    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
970    where
971        S: Serializer,
972    {
973        use Format::*;
974
975        match self.format {
976            Variable(_) => Err(serde::ser::Error::custom(
977                "Required formats cannot contain variables",
978            )),
979            TypeName(name) => {
980                if let Some(container_format) = self.registry.get(name) {
981                    serialize_container_format(
982                        name,
983                        container_format,
984                        self.value,
985                        self.registry,
986                        self.environment,
987                        serializer,
988                    )
989                } else {
990                    self.environment.serialize(name, self.value, serializer)
991                }
992            }
993            Unit => serializer.serialize_unit(),
994            Bool => match self.value {
995                Value::Bool(b) => serializer.serialize_bool(*b),
996                _ => Err(serde::ser::Error::custom("Expected bool value")),
997            },
998            I8 => serialize_integer::<S, i8>(self.value, serializer),
999            I16 => serialize_integer::<S, i16>(self.value, serializer),
1000            I32 => serialize_integer::<S, i32>(self.value, serializer),
1001            I64 => serialize_integer::<S, i64>(self.value, serializer),
1002            I128 => serialize_integer_or_string::<S, i128>(self.value, serializer),
1003            U8 => serialize_integer::<S, u8>(self.value, serializer),
1004            U16 => serialize_integer::<S, u16>(self.value, serializer),
1005            U32 => serialize_integer::<S, u32>(self.value, serializer),
1006            U64 => serialize_integer::<S, u64>(self.value, serializer),
1007            U128 => serialize_integer_or_string::<S, u128>(self.value, serializer),
1008            F32 => serialize_f32(self.value, serializer),
1009            F64 => serialize_f64(self.value, serializer),
1010            Char => match self.value {
1011                Value::String(s) => {
1012                    let mut chars = s.chars();
1013                    if let Some(c) = chars.next() {
1014                        if chars.next().is_none() {
1015                            serializer.serialize_char(c)
1016                        } else {
1017                            Err(serde::ser::Error::custom(
1018                                "Expected single character string",
1019                            ))
1020                        }
1021                    } else {
1022                        Err(serde::ser::Error::custom("Expected non-empty string"))
1023                    }
1024                }
1025                _ => Err(serde::ser::Error::custom("Expected string for char")),
1026            },
1027            Str => match self.value {
1028                Value::String(s) => serializer.serialize_str(s),
1029                _ => Err(serde::ser::Error::custom("Expected string value")),
1030            },
1031            Bytes => match self.value {
1032                Value::Array(arr) => {
1033                    let bytes: Result<Vec<u8>, _> = arr
1034                        .iter()
1035                        .map(|v| match v {
1036                            Value::Number(n) => n
1037                                .as_u64()
1038                                .and_then(|n| u8::try_from(n).ok())
1039                                .ok_or_else(|| {
1040                                    serde::ser::Error::custom("Invalid byte value in array")
1041                                }),
1042                            _ => Err(serde::ser::Error::custom("Expected number in byte array")),
1043                        })
1044                        .collect();
1045                    serializer.serialize_bytes(&bytes?)
1046                }
1047                _ => Err(serde::ser::Error::custom("Expected array for bytes")),
1048            },
1049            Option(inner_format) => match self.value {
1050                Value::Null => serializer.serialize_none(),
1051                _ => serializer.serialize_some(&SerializationContext {
1052                    value: self.value,
1053                    format: inner_format,
1054                    registry: self.registry,
1055                    environment: self.environment,
1056                }),
1057            },
1058            Seq(inner_format) => match self.value {
1059                Value::Array(arr) => {
1060                    let mut seq = serializer.serialize_seq(Some(arr.len()))?;
1061                    for item in arr {
1062                        seq.serialize_element(&SerializationContext {
1063                            value: item,
1064                            format: inner_format,
1065                            registry: self.registry,
1066                            environment: self.environment,
1067                        })?;
1068                    }
1069                    seq.end()
1070                }
1071                _ => Err(serde::ser::Error::custom("Expected array for sequence")),
1072            },
1073            Map { key, value } => match self.value {
1074                Value::Object(obj) => {
1075                    let mut map = serializer.serialize_map(Some(obj.len()))?;
1076                    for (k, v) in obj {
1077                        map.serialize_entry(
1078                            &SerializationContext {
1079                                value: &Value::String(k.clone()),
1080                                format: key,
1081                                registry: self.registry,
1082                                environment: self.environment,
1083                            },
1084                            &SerializationContext {
1085                                value: v,
1086                                format: value,
1087                                registry: self.registry,
1088                                environment: self.environment,
1089                            },
1090                        )?;
1091                    }
1092                    map.end()
1093                }
1094                _ => Err(serde::ser::Error::custom("Expected object for map")),
1095            },
1096            Tuple(formats) => match self.value {
1097                Value::Array(arr) => {
1098                    if arr.len() != formats.len() {
1099                        return Err(serde::ser::Error::custom(format!(
1100                            "Expected tuple of length {}, got {}",
1101                            formats.len(),
1102                            arr.len()
1103                        )));
1104                    }
1105                    let mut tuple = serializer.serialize_tuple(formats.len())?;
1106                    for (item, format) in arr.iter().zip(formats.iter()) {
1107                        tuple.serialize_element(&SerializationContext {
1108                            value: item,
1109                            format,
1110                            registry: self.registry,
1111                            environment: self.environment,
1112                        })?;
1113                    }
1114                    tuple.end()
1115                }
1116                _ => Err(serde::ser::Error::custom("Expected array for tuple")),
1117            },
1118            TupleArray { content, size } => match self.value {
1119                Value::Array(arr) => {
1120                    if arr.len() != *size {
1121                        return Err(serde::ser::Error::custom(format!(
1122                            "Expected array of length {}, got {}",
1123                            size,
1124                            arr.len()
1125                        )));
1126                    }
1127                    let mut tuple = serializer.serialize_tuple(*size)?;
1128                    for item in arr {
1129                        tuple.serialize_element(&SerializationContext {
1130                            value: item,
1131                            format: content,
1132                            registry: self.registry,
1133                            environment: self.environment,
1134                        })?;
1135                    }
1136                    tuple.end()
1137                }
1138                _ => Err(serde::ser::Error::custom("Expected array for tuple array")),
1139            },
1140        }
1141    }
1142}
1143
1144fn serialize_integer<S, I>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
1145where
1146    S: Serializer,
1147    I: TryFrom<i64> + TryFrom<u64> + Serialize,
1148{
1149    match value {
1150        Value::Number(n) => {
1151            if let Some(i) = n.as_i64() {
1152                let converted = I::try_from(i)
1153                    .map_err(|_| serde::ser::Error::custom("Integer out of range"))?;
1154                converted.serialize(serializer)
1155            } else if let Some(u) = n.as_u64() {
1156                let converted = I::try_from(u)
1157                    .map_err(|_| serde::ser::Error::custom("Integer out of range"))?;
1158                converted.serialize(serializer)
1159            } else {
1160                Err(serde::ser::Error::custom("Invalid number"))
1161            }
1162        }
1163        _ => Err(serde::ser::Error::custom("Expected number")),
1164    }
1165}
1166
1167fn serialize_integer_or_string<S, I>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
1168where
1169    S: Serializer,
1170    I: TryFrom<i64> + TryFrom<u64> + std::str::FromStr + Serialize,
1171{
1172    match value {
1173        Value::Number(n) => {
1174            if let Some(i) = n.as_i64() {
1175                let converted = I::try_from(i)
1176                    .map_err(|_| serde::ser::Error::custom("Integer out of range"))?;
1177                converted.serialize(serializer)
1178            } else if let Some(u) = n.as_u64() {
1179                let converted = I::try_from(u)
1180                    .map_err(|_| serde::ser::Error::custom("Integer out of range"))?;
1181                converted.serialize(serializer)
1182            } else {
1183                Err(serde::ser::Error::custom("Invalid number"))
1184            }
1185        }
1186        Value::String(s) => {
1187            let converted = s
1188                .parse::<I>()
1189                .map_err(|_| serde::ser::Error::custom("Invalid integer string"))?;
1190            converted.serialize(serializer)
1191        }
1192        _ => Err(serde::ser::Error::custom("Expected number or string")),
1193    }
1194}
1195
1196fn serialize_f32<S>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
1197where
1198    S: Serializer,
1199{
1200    match value {
1201        Value::Number(n) => {
1202            if let Some(f) = n.as_f64() {
1203                serializer.serialize_f32(f as f32)
1204            } else {
1205                Err(serde::ser::Error::custom("Invalid float"))
1206            }
1207        }
1208        _ => Err(serde::ser::Error::custom("Expected number for float")),
1209    }
1210}
1211
1212fn serialize_f64<S>(value: &Value, serializer: S) -> Result<S::Ok, S::Error>
1213where
1214    S: Serializer,
1215{
1216    match value {
1217        Value::Number(n) => {
1218            if let Some(f) = n.as_f64() {
1219                serializer.serialize_f64(f)
1220            } else {
1221                Err(serde::ser::Error::custom("Invalid float"))
1222            }
1223        }
1224        _ => Err(serde::ser::Error::custom("Expected number for float")),
1225    }
1226}
1227
1228fn serialize_container_format<S, E>(
1229    name: &str,
1230    container_format: &ContainerFormat,
1231    value: &Value,
1232    registry: &Registry,
1233    environment: &E,
1234    serializer: S,
1235) -> Result<S::Ok, S::Error>
1236where
1237    S: Serializer,
1238    E: SerializationEnvironment,
1239{
1240    use ContainerFormat::*;
1241
1242    let static_name = environment.get_static_name(name);
1243
1244    match container_format {
1245        UnitStruct => serializer.serialize_unit_struct(static_name),
1246        NewTypeStruct(format) => {
1247            let context = SerializationContext {
1248                value,
1249                format,
1250                registry,
1251                environment,
1252            };
1253            serializer.serialize_newtype_struct(static_name, &context)
1254        }
1255        TupleStruct(formats) => match value {
1256            Value::Array(arr) => {
1257                if arr.len() != formats.len() {
1258                    return Err(serde::ser::Error::custom(format!(
1259                        "Expected tuple struct of length {}, got {}",
1260                        formats.len(),
1261                        arr.len()
1262                    )));
1263                }
1264                let mut tuple_struct =
1265                    serializer.serialize_tuple_struct(static_name, formats.len())?;
1266                for (item, format) in arr.iter().zip(formats.iter()) {
1267                    tuple_struct.serialize_field(&SerializationContext {
1268                        value: item,
1269                        format,
1270                        registry,
1271                        environment,
1272                    })?;
1273                }
1274                tuple_struct.end()
1275            }
1276            _ => Err(serde::ser::Error::custom("Expected array for tuple struct")),
1277        },
1278        Struct(fields) => match value {
1279            Value::Object(obj) => {
1280                let mut struct_ser = serializer.serialize_struct(static_name, fields.len())?;
1281                for field in fields {
1282                    let field_value = obj.get(&field.name).ok_or_else(|| {
1283                        serde::ser::Error::custom(format!("Missing field: {}", field.name))
1284                    })?;
1285                    let static_field_name = environment.get_static_name(&field.name);
1286                    struct_ser.serialize_field(
1287                        static_field_name,
1288                        &SerializationContext {
1289                            value: field_value,
1290                            format: &field.value,
1291                            registry,
1292                            environment,
1293                        },
1294                    )?;
1295                }
1296                struct_ser.end()
1297            }
1298            _ => Err(serde::ser::Error::custom("Expected object for struct")),
1299        },
1300        Enum(variants) => match value {
1301            Value::Object(obj) => {
1302                if obj.len() != 1 {
1303                    return Err(serde::ser::Error::custom(
1304                        "Expected object with single variant key",
1305                    ));
1306                }
1307                let (variant_name, variant_value) = obj.iter().next().unwrap();
1308
1309                // Find the variant by name
1310                let (variant_index, variant_format) = variants
1311                    .iter()
1312                    .find(|(_, v)| v.name == *variant_name)
1313                    .ok_or_else(|| {
1314                        serde::ser::Error::custom(format!("Unknown variant: {}", variant_name))
1315                    })?;
1316
1317                serialize_enum_variant(
1318                    static_name,
1319                    *variant_index,
1320                    variant_name,
1321                    &variant_format.value,
1322                    variant_value,
1323                    registry,
1324                    environment,
1325                    serializer,
1326                )
1327            }
1328            _ => Err(serde::ser::Error::custom("Expected object for enum")),
1329        },
1330    }
1331}
1332
1333#[allow(clippy::too_many_arguments)]
1334fn serialize_enum_variant<S, E>(
1335    enum_name: &'static str,
1336    variant_index: u32,
1337    variant_name: &str,
1338    variant_format: &VariantFormat,
1339    value: &Value,
1340    registry: &Registry,
1341    environment: &E,
1342    serializer: S,
1343) -> Result<S::Ok, S::Error>
1344where
1345    S: Serializer,
1346    E: SerializationEnvironment,
1347{
1348    use VariantFormat::*;
1349
1350    let static_variant_name = environment.get_static_name(variant_name);
1351
1352    match variant_format {
1353        Variable(_) => Err(serde::ser::Error::custom(
1354            "Variant format cannot contain variables",
1355        )),
1356        Unit => match value {
1357            Value::Null => {
1358                serializer.serialize_unit_variant(enum_name, variant_index, static_variant_name)
1359            }
1360            _ => Err(serde::ser::Error::custom("Expected null for unit variant")),
1361        },
1362        NewType(format) => {
1363            let context = SerializationContext {
1364                value,
1365                format,
1366                registry,
1367                environment,
1368            };
1369            serializer.serialize_newtype_variant(
1370                enum_name,
1371                variant_index,
1372                static_variant_name,
1373                &context,
1374            )
1375        }
1376        Tuple(formats) => match value {
1377            Value::Array(arr) => {
1378                if arr.len() != formats.len() {
1379                    return Err(serde::ser::Error::custom(format!(
1380                        "Expected tuple variant of length {}, got {}",
1381                        formats.len(),
1382                        arr.len()
1383                    )));
1384                }
1385                let mut tuple_variant = serializer.serialize_tuple_variant(
1386                    enum_name,
1387                    variant_index,
1388                    static_variant_name,
1389                    formats.len(),
1390                )?;
1391                for (item, format) in arr.iter().zip(formats.iter()) {
1392                    tuple_variant.serialize_field(&SerializationContext {
1393                        value: item,
1394                        format,
1395                        registry,
1396                        environment,
1397                    })?;
1398                }
1399                tuple_variant.end()
1400            }
1401            _ => Err(serde::ser::Error::custom(
1402                "Expected array for tuple variant",
1403            )),
1404        },
1405        Struct(fields) => match value {
1406            Value::Object(obj) => {
1407                let mut struct_variant = serializer.serialize_struct_variant(
1408                    enum_name,
1409                    variant_index,
1410                    static_variant_name,
1411                    fields.len(),
1412                )?;
1413                for field in fields {
1414                    let field_value = obj.get(&field.name).ok_or_else(|| {
1415                        serde::ser::Error::custom(format!("Missing field: {}", field.name))
1416                    })?;
1417                    let static_field_name = environment.get_static_name(&field.name);
1418                    struct_variant.serialize_field(
1419                        static_field_name,
1420                        &SerializationContext {
1421                            value: field_value,
1422                            format: &field.value,
1423                            registry,
1424                            environment,
1425                        },
1426                    )?;
1427                }
1428                struct_variant.end()
1429            }
1430            _ => Err(serde::ser::Error::custom(
1431                "Expected object for struct variant",
1432            )),
1433        },
1434    }
1435}