miden_protocol/account/component/storage/toml/
serde_impls.rs1use 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
10impl 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
124impl 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}