Skip to main content

miden_protocol/account/component/storage/toml/
serde_impls.rs

1use alloc::string::{String, ToString};
2
3use serde::de::Error as _;
4use serde::ser::{Error as SerError, SerializeStruct};
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6
7use super::super::type_registry::SCHEMA_TYPE_REGISTRY;
8use super::super::{FeltSchema, SchemaTypeId, WordValue};
9
10// FELT SCHEMA SERIALIZATION
11// ================================================================================================
12
13impl Serialize for FeltSchema {
14    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
15    where
16        S: Serializer,
17    {
18        if self.felt_type() == SchemaTypeId::void() {
19            let mut state = serializer.serialize_struct("FeltSchema", 2)?;
20            state.serialize_field("type", &SchemaTypeId::void())?;
21            if let Some(description) = self.description() {
22                state.serialize_field("description", description)?;
23            }
24            return state.end();
25        }
26
27        let name = self.name().ok_or_else(|| {
28            SerError::custom("invalid FeltSchema: non-void elements must have a name")
29        })?;
30
31        let mut state = serializer.serialize_struct("FeltSchema", 4)?;
32        state.serialize_field("name", name)?;
33        if let Some(description) = self.description() {
34            state.serialize_field("description", description)?;
35        }
36        if self.felt_type() != SchemaTypeId::native_felt() {
37            state.serialize_field("type", &self.felt_type())?;
38        }
39        if let Some(default_value) = self.default_value() {
40            state.serialize_field(
41                "default-value",
42                &SCHEMA_TYPE_REGISTRY.display_felt(&self.felt_type(), default_value),
43            )?;
44        }
45        state.end()
46    }
47}
48
49impl<'de> Deserialize<'de> for FeltSchema {
50    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
51    where
52        D: Deserializer<'de>,
53    {
54        #[derive(Deserialize)]
55        #[serde(rename_all = "kebab-case", deny_unknown_fields)]
56        struct RawFeltSchema {
57            #[serde(default)]
58            name: Option<String>,
59            #[serde(default)]
60            description: Option<String>,
61            #[serde(default, rename = "default-value")]
62            default_value: Option<String>,
63            #[serde(default, rename = "type")]
64            r#type: Option<SchemaTypeId>,
65        }
66
67        let raw = RawFeltSchema::deserialize(deserializer)?;
68
69        let felt_type = raw.r#type.unwrap_or_else(SchemaTypeId::native_felt);
70
71        let description = raw.description.and_then(|description| {
72            if description.trim().is_empty() {
73                None
74            } else {
75                Some(description)
76            }
77        });
78
79        if felt_type == SchemaTypeId::void() {
80            if raw.name.is_some() {
81                return Err(D::Error::custom("`type = \"void\"` elements must omit `name`"));
82            }
83            if raw.default_value.is_some() {
84                return Err(D::Error::custom(
85                    "`type = \"void\"` elements cannot define `default-value`",
86                ));
87            }
88
89            let schema = FeltSchema::new_void();
90            return Ok(match description {
91                Some(description) => schema.with_description(description),
92                None => schema,
93            });
94        }
95
96        let Some(name) = raw.name else {
97            return Err(D::Error::custom("non-void elements must define `name`"));
98        };
99
100        let default_value = raw
101            .default_value
102            .map(|default_value| {
103                SCHEMA_TYPE_REGISTRY.try_parse_felt(&felt_type, &default_value).map_err(|err| {
104                    D::Error::custom(format!(
105                        "failed to parse {felt_type} as Felt for `default-value`: {err}"
106                    ))
107                })
108            })
109            .transpose()?;
110
111        let schema = match default_value {
112            Some(default_value) => {
113                FeltSchema::new_typed_with_default(felt_type, name, default_value)
114            },
115            None => FeltSchema::new_typed(felt_type, name),
116        };
117        Ok(match description {
118            Some(description) => schema.with_description(description),
119            None => schema,
120        })
121    }
122}
123
124// WORD VALUE SERIALIZATION
125// ================================================================================================
126
127impl Serialize for WordValue {
128    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
129    where
130        S: Serializer,
131    {
132        match self {
133            WordValue::Atomic(value) => serializer.serialize_str(value),
134            WordValue::Elements(elements) => elements.serialize(serializer),
135            WordValue::FullyTyped(word) => serializer.serialize_str(&word.to_string()),
136        }
137    }
138}
139
140impl<'de> Deserialize<'de> for WordValue {
141    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
142    where
143        D: Deserializer<'de>,
144    {
145        #[derive(Deserialize)]
146        #[serde(untagged)]
147        enum RawWordValue {
148            Atomic(String),
149            Elements([String; 4]),
150        }
151
152        match RawWordValue::deserialize(deserializer)? {
153            RawWordValue::Atomic(value) => Ok(WordValue::Atomic(value)),
154            RawWordValue::Elements(elements) => Ok(WordValue::Elements(elements)),
155        }
156    }
157}