1use crate::parsing::ast::Span;
2use crate::planning::ExecutionPlan;
3use crate::semantic::{FactPath, LemmaFact, LemmaType, LiteralValue};
4use crate::LemmaError;
5use crate::Source;
6use serde::{Deserialize, Deserializer, Serializer};
7use serde_json::Value;
8use std::collections::{HashMap, HashSet};
9use std::sync::Arc;
10
11pub fn from_json(json: &[u8], plan: &ExecutionPlan) -> Result<HashMap<String, String>, LemmaError> {
16 let map: HashMap<String, Value> = serde_json::from_slice(json).map_err(|e| {
17 LemmaError::engine(
18 format!("JSON parse error: {}", e),
19 Span {
20 start: 0,
21 end: 0,
22 line: 1,
23 col: 0,
24 },
25 "<input>",
26 Arc::from(""),
27 &plan.doc_name,
28 1,
29 None::<String>,
30 )
31 })?;
32
33 Ok(map
34 .into_iter()
35 .filter(|(_, v)| !v.is_null())
36 .map(|(k, v)| (k, json_value_to_string(&v)))
37 .collect())
38}
39
40fn json_value_to_string(value: &Value) -> String {
41 match value {
42 Value::String(s) => s.clone(),
43 Value::Number(n) => n.to_string(),
44 Value::Bool(b) => b.to_string(),
45 Value::Array(_) | Value::Object(_) => serde_json::to_string(value).unwrap_or_default(),
46 Value::Null => String::new(),
47 }
48}
49
50pub fn serialize_fact_path_map<S>(
55 map: &HashMap<FactPath, LemmaFact>,
56 serializer: S,
57) -> Result<S::Ok, S::Error>
58where
59 S: Serializer,
60{
61 use serde::ser::SerializeMap;
62 let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
63 for (key, value) in map {
64 map_serializer.serialize_entry(&key.to_string(), value)?;
65 }
66 map_serializer.end()
67}
68
69pub fn deserialize_fact_path_map<'de, D>(
73 deserializer: D,
74) -> Result<HashMap<FactPath, LemmaFact>, D::Error>
75where
76 D: Deserializer<'de>,
77{
78 let map: HashMap<String, LemmaFact> = HashMap::deserialize(deserializer)?;
79 let mut result = HashMap::new();
80 for (key_str, value) in map {
81 let path_parts: Vec<String> = key_str.split('.').map(|s| s.to_string()).collect();
82 let fact_path = FactPath::from_path(path_parts);
83 result.insert(fact_path, value);
84 }
85 Ok(result)
86}
87
88pub fn serialize_fact_type_map<S>(
93 map: &HashMap<FactPath, LemmaType>,
94 serializer: S,
95) -> Result<S::Ok, S::Error>
96where
97 S: Serializer,
98{
99 use serde::ser::SerializeMap;
100 let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
101 for (key, value) in map {
102 map_serializer.serialize_entry(&key.to_string(), value)?;
103 }
104 map_serializer.end()
105}
106
107pub fn deserialize_fact_type_map<'de, D>(
111 deserializer: D,
112) -> Result<HashMap<FactPath, LemmaType>, D::Error>
113where
114 D: Deserializer<'de>,
115{
116 let map: HashMap<String, LemmaType> = HashMap::deserialize(deserializer)?;
117 let mut result = HashMap::new();
118 for (key_str, value) in map {
119 let path_parts: Vec<String> = key_str.split('.').map(|s| s.to_string()).collect();
120 let fact_path = FactPath::from_path(path_parts);
121 result.insert(fact_path, value);
122 }
123 Ok(result)
124}
125
126pub fn serialize_fact_value_map<S>(
131 map: &HashMap<FactPath, LiteralValue>,
132 serializer: S,
133) -> Result<S::Ok, S::Error>
134where
135 S: Serializer,
136{
137 use serde::ser::SerializeMap;
138 let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
139 for (key, value) in map {
140 map_serializer.serialize_entry(&key.to_string(), value)?;
141 }
142 map_serializer.end()
143}
144
145pub fn deserialize_fact_value_map<'de, D>(
149 deserializer: D,
150) -> Result<HashMap<FactPath, LiteralValue>, D::Error>
151where
152 D: Deserializer<'de>,
153{
154 let map: HashMap<String, LiteralValue> = HashMap::deserialize(deserializer)?;
155 let mut result = HashMap::new();
156 for (key_str, value) in map {
157 let path_parts: Vec<String> = key_str.split('.').map(|s| s.to_string()).collect();
158 let fact_path = FactPath::from_path(path_parts);
159 result.insert(fact_path, value);
160 }
161 Ok(result)
162}
163
164pub fn serialize_fact_doc_ref_map<S>(
166 map: &HashMap<FactPath, String>,
167 serializer: S,
168) -> Result<S::Ok, S::Error>
169where
170 S: Serializer,
171{
172 use serde::ser::SerializeMap;
173 let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
174 for (key, value) in map {
175 map_serializer.serialize_entry(&key.to_string(), value)?;
176 }
177 map_serializer.end()
178}
179
180pub fn deserialize_fact_doc_ref_map<'de, D>(
182 deserializer: D,
183) -> Result<HashMap<FactPath, String>, D::Error>
184where
185 D: Deserializer<'de>,
186{
187 let map: HashMap<String, String> = HashMap::deserialize(deserializer)?;
188 let mut result = HashMap::new();
189 for (key_str, value) in map {
190 let path_parts: Vec<String> = key_str.split('.').map(|s| s.to_string()).collect();
191 let fact_path = FactPath::from_path(path_parts);
192 result.insert(fact_path, value);
193 }
194 Ok(result)
195}
196
197pub fn serialize_fact_source_map<S>(
199 map: &HashMap<FactPath, Source>,
200 serializer: S,
201) -> Result<S::Ok, S::Error>
202where
203 S: Serializer,
204{
205 use serde::ser::SerializeMap;
206 let mut map_serializer = serializer.serialize_map(Some(map.len()))?;
207 for (key, value) in map {
208 map_serializer.serialize_entry(&key.to_string(), value)?;
209 }
210 map_serializer.end()
211}
212
213pub fn deserialize_fact_source_map<'de, D>(
215 deserializer: D,
216) -> Result<HashMap<FactPath, Source>, D::Error>
217where
218 D: Deserializer<'de>,
219{
220 let map: HashMap<String, Source> = HashMap::deserialize(deserializer)?;
221 let mut result = HashMap::new();
222 for (key_str, value) in map {
223 let path_parts: Vec<String> = key_str.split('.').map(|s| s.to_string()).collect();
224 let fact_path = FactPath::from_path(path_parts);
225 result.insert(fact_path, value);
226 }
227 Ok(result)
228}
229
230pub fn serialize_fact_path_set<S>(set: &HashSet<FactPath>, serializer: S) -> Result<S::Ok, S::Error>
234where
235 S: Serializer,
236{
237 use serde::ser::SerializeSeq;
238 let mut seq = serializer.serialize_seq(Some(set.len()))?;
239 for item in set {
240 seq.serialize_element(&item.to_string())?;
241 }
242 seq.end()
243}
244
245pub fn deserialize_fact_path_set<'de, D>(deserializer: D) -> Result<HashSet<FactPath>, D::Error>
249where
250 D: Deserializer<'de>,
251{
252 let vec: Vec<String> = Vec::deserialize(deserializer)?;
253 let mut result = HashSet::new();
254 for key_str in vec {
255 let path_parts: Vec<String> = key_str.split('.').map(|s| s.to_string()).collect();
256 let fact_path = FactPath::from_path(path_parts);
257 result.insert(fact_path);
258 }
259 Ok(result)
260}
261
262#[cfg(test)]
263mod tests {
264 use super::*;
265 fn create_test_plan() -> ExecutionPlan {
266 ExecutionPlan {
267 doc_name: "test".to_string(),
268 fact_schema: HashMap::new(),
269 fact_values: HashMap::new(),
270 doc_refs: HashMap::new(),
271 fact_sources: HashMap::new(),
272 rules: vec![],
273 sources: HashMap::from([("<test>".to_string(), "".to_string())]),
274 }
275 }
276
277 #[test]
278 fn test_json_string_to_string() {
279 let plan = create_test_plan();
280 let json = br#"{"name": "Alice"}"#;
281 let result = from_json(json, &plan).unwrap();
282 assert_eq!(result.get("name"), Some(&"Alice".to_string()));
283 }
284
285 #[test]
286 fn test_json_number_to_string() {
287 let plan = create_test_plan();
288 let json = br#"{"name": 42}"#;
289 let result = from_json(json, &plan).unwrap();
290 assert_eq!(result.get("name"), Some(&"42".to_string()));
291 }
292
293 #[test]
294 fn test_json_boolean_to_string() {
295 let plan = create_test_plan();
296 let json = br#"{"name": true}"#;
297 let result = from_json(json, &plan).unwrap();
298 assert_eq!(result.get("name"), Some(&"true".to_string()));
299 }
300
301 #[test]
302 fn test_json_array_to_string() {
303 let plan = create_test_plan();
304 let json = br#"{"data": [1, 2, 3]}"#;
305 let result = from_json(json, &plan).unwrap();
306 assert_eq!(result.get("data"), Some(&"[1,2,3]".to_string()));
307 }
308
309 #[test]
310 fn test_json_object_to_string() {
311 let plan = create_test_plan();
312 let json = br#"{"config": {"key": "value"}}"#;
313 let result = from_json(json, &plan).unwrap();
314 assert_eq!(
315 result.get("config"),
316 Some(&"{\"key\":\"value\"}".to_string())
317 );
318 }
319
320 #[test]
321 fn test_null_value_skipped() {
322 let plan = create_test_plan();
323 let json = br#"{"name": null, "age": 30}"#;
324 let result = from_json(json, &plan).unwrap();
325 assert_eq!(result.len(), 1);
326 assert!(!result.contains_key("name"));
327 assert_eq!(result.get("age"), Some(&"30".to_string()));
328 }
329
330 #[test]
331 fn test_all_null_values() {
332 let plan = create_test_plan();
333 let json = br#"{"name": null}"#;
334 let result = from_json(json, &plan).unwrap();
335 assert!(result.is_empty());
336 }
337
338 #[test]
339 fn test_mixed_valid_types() {
340 let plan = create_test_plan();
341 let json = br#"{"name": "Test", "count": 5, "active": true, "discount": 21}"#;
342 let result = from_json(json, &plan).unwrap();
343 assert_eq!(result.len(), 4);
344 assert_eq!(result.get("name"), Some(&"Test".to_string()));
345 assert_eq!(result.get("count"), Some(&"5".to_string()));
346 assert_eq!(result.get("active"), Some(&"true".to_string()));
347 assert_eq!(result.get("discount"), Some(&"21".to_string()));
348 }
349
350 #[test]
351 fn test_invalid_json_syntax() {
352 let plan = create_test_plan();
353 let json = br#"{"name": }"#;
354 let result = from_json(json, &plan);
355 assert!(result.is_err());
356 let error_message = result.unwrap_err().to_string();
357 assert!(error_message.contains("JSON parse error"));
358 }
359}