mon_core/
serialization.rs1use crate::ast::{Member, MonValue, MonValueKind};
44use serde::Serialize;
45use std::collections::BTreeMap;
46
47#[derive(Debug, Clone, PartialEq, Serialize)]
48#[serde(untagged)]
49pub enum Value {
50 String(String),
51 Number(f64),
52 Boolean(bool),
53 Null,
54 Array(Vec<Value>),
55 Object(BTreeMap<String, Value>),
56}
57
58pub(crate) fn to_value(mon_value: &MonValue) -> Value {
59 match &mon_value.kind {
60 MonValueKind::String(s) => Value::String(s.clone()),
61 MonValueKind::Number(n) => Value::Number(*n),
62 MonValueKind::Boolean(b) => Value::Boolean(*b),
63 MonValueKind::Array(arr) => Value::Array(arr.iter().map(to_value).collect()),
64 MonValueKind::Object(obj) => {
65 let mut map = BTreeMap::new();
66 for member in obj {
67 if let Member::Pair(pair) = member {
68 map.insert(pair.key.clone(), to_value(&pair.value));
71 }
72 }
73 Value::Object(map)
74 }
75 MonValueKind::Null
78 | MonValueKind::Alias(_)
79 | MonValueKind::EnumValue { .. }
80 | MonValueKind::ArraySpread(_) => Value::Null, }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::ast::{Member, MonValue, MonValueKind, Pair};
88 use std::collections::BTreeMap;
89
90 fn make_value(kind: MonValueKind) -> MonValue {
91 MonValue {
92 kind,
93 anchor: None,
94 pos_start: 0,
95 pos_end: 0,
96 }
97 }
98
99 #[test]
100 fn test_string_conversion() {
101 let mon_val = make_value(MonValueKind::String("hello".to_string()));
102 let result = to_value(&mon_val);
103 assert_eq!(result, Value::String("hello".to_string()));
104 }
105
106 #[test]
107 fn test_number_conversion() {
108 let mon_val = make_value(MonValueKind::Number(42.5));
109 let result = to_value(&mon_val);
110 assert_eq!(result, Value::Number(42.5));
111 }
112
113 #[test]
114 fn test_boolean_conversion() {
115 let mon_val = make_value(MonValueKind::Boolean(true));
116 assert_eq!(to_value(&mon_val), Value::Boolean(true));
117
118 let mon_val2 = make_value(MonValueKind::Boolean(false));
119 assert_eq!(to_value(&mon_val2), Value::Boolean(false));
120 }
121
122 #[test]
123 fn test_null_conversion() {
124 let mon_val = make_value(MonValueKind::Null);
125 assert_eq!(to_value(&mon_val), Value::Null);
126 }
127
128 #[test]
129 fn test_array_conversion() {
130 let arr = vec![
131 make_value(MonValueKind::Number(1.0)),
132 make_value(MonValueKind::Number(2.0)),
133 make_value(MonValueKind::Number(3.0)),
134 ];
135 let mon_val = make_value(MonValueKind::Array(arr));
136 let result = to_value(&mon_val);
137
138 assert_eq!(
139 result,
140 Value::Array(vec![
141 Value::Number(1.0),
142 Value::Number(2.0),
143 Value::Number(3.0),
144 ])
145 );
146 }
147
148 #[test]
149 fn test_object_conversion() {
150 let pair = Pair {
151 key: "test".to_string(),
152 value: make_value(MonValueKind::String("value".to_string())),
153 validation: None,
154 };
155 let obj = vec![Member::Pair(pair)];
156 let mon_val = make_value(MonValueKind::Object(obj));
157 let result = to_value(&mon_val);
158
159 let mut expected_map = BTreeMap::new();
160 expected_map.insert("test".to_string(), Value::String("value".to_string()));
161 assert_eq!(result, Value::Object(expected_map));
162 }
163
164 #[test]
165 fn test_object_excludes_non_pair_members() {
166 let pair = Pair {
167 key: "data".to_string(),
168 value: make_value(MonValueKind::Number(123.0)),
169 validation: None,
170 };
171 let obj = vec![Member::Pair(pair), Member::Spread("ignored".to_string())];
172 let mon_val = make_value(MonValueKind::Object(obj));
173 let result = to_value(&mon_val);
174
175 let mut expected_map = BTreeMap::new();
176 expected_map.insert("data".to_string(), Value::Number(123.0));
177 assert_eq!(result, Value::Object(expected_map));
178 }
179
180 #[test]
181 fn test_alias_converts_to_null() {
182 let mon_val = make_value(MonValueKind::Alias("some_anchor".to_string()));
183 assert_eq!(to_value(&mon_val), Value::Null);
184 }
185
186 #[test]
187 fn test_enum_value_converts_to_null() {
188 let mon_val = make_value(MonValueKind::EnumValue {
189 enum_name: "Status".to_string(),
190 variant_name: "Active".to_string(),
191 });
192 assert_eq!(to_value(&mon_val), Value::Null);
193 }
194
195 #[test]
196 fn test_array_spread_converts_to_null() {
197 let mon_val = make_value(MonValueKind::ArraySpread("anchor".to_string()));
198 assert_eq!(to_value(&mon_val), Value::Null);
199 }
200
201 #[test]
202 fn test_nested_object() {
203 let inner_pair = Pair {
204 key: "inner".to_string(),
205 value: make_value(MonValueKind::Number(42.0)),
206 validation: None,
207 };
208 let inner_obj = vec![Member::Pair(inner_pair)];
209 let outer_pair = Pair {
210 key: "outer".to_string(),
211 value: make_value(MonValueKind::Object(inner_obj)),
212 validation: None,
213 };
214 let outer_obj = vec![Member::Pair(outer_pair)];
215 let mon_val = make_value(MonValueKind::Object(outer_obj));
216
217 let result = to_value(&mon_val);
218
219 let mut inner_map = BTreeMap::new();
220 inner_map.insert("inner".to_string(), Value::Number(42.0));
221 let mut outer_map = BTreeMap::new();
222 outer_map.insert("outer".to_string(), Value::Object(inner_map));
223
224 assert_eq!(result, Value::Object(outer_map));
225 }
226}