windjammer_runtime/
json.rs1use serde_json::Value;
6
7pub fn parse(s: &str) -> Result<Value, String> {
9 serde_json::from_str(s).map_err(|e| e.to_string())
10}
11
12pub fn stringify(value: &Value) -> Result<String, String> {
14 serde_json::to_string(value).map_err(|e| e.to_string())
15}
16
17pub fn stringify_pretty(value: &Value) -> Result<String, String> {
19 serde_json::to_string_pretty(value).map_err(|e| e.to_string())
20}
21
22pub fn object() -> Value {
24 Value::Object(serde_json::Map::new())
25}
26
27pub fn array() -> Value {
29 Value::Array(Vec::new())
30}
31
32pub fn null() -> Value {
34 Value::Null
35}
36
37pub fn boolean(b: bool) -> Value {
39 Value::Bool(b)
40}
41
42pub fn number_i64(n: i64) -> Value {
44 Value::Number(n.into())
45}
46
47pub fn number_f64(n: f64) -> Result<Value, String> {
49 serde_json::Number::from_f64(n)
50 .map(Value::Number)
51 .ok_or_else(|| "Invalid number".to_string())
52}
53
54pub fn string(s: &str) -> Value {
56 Value::String(s.to_string())
57}
58
59pub fn get<'a>(value: &'a Value, key: &str) -> Option<&'a Value> {
61 value.get(key)
62}
63
64pub fn get_string(value: &Value, key: &str) -> Option<String> {
66 value
67 .get(key)
68 .and_then(|v| v.as_str().map(|s| s.to_string()))
69}
70
71pub fn get_number(value: &Value, key: &str) -> Option<f64> {
73 value.get(key).and_then(|v| v.as_f64())
74}
75
76pub fn get_bool(value: &Value, key: &str) -> Option<bool> {
78 value.get(key).and_then(|v| v.as_bool())
79}
80
81pub fn set(value: &mut Value, key: &str, new_value: Value) -> Result<(), String> {
83 if let Some(obj) = value.as_object_mut() {
84 obj.insert(key.to_string(), new_value);
85 Ok(())
86 } else {
87 Err("Value is not an object".to_string())
88 }
89}
90
91pub fn len(value: &Value) -> usize {
93 match value {
94 Value::Array(arr) => arr.len(),
95 Value::Object(obj) => obj.len(),
96 _ => 0,
97 }
98}
99
100pub fn is_empty(value: &Value) -> bool {
102 len(value) == 0
103}
104
105pub fn get_index(value: &Value, index: usize) -> Option<&Value> {
107 value.get(index)
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn test_parse_stringify() {
116 let json_str = r#"{"name":"Alice","age":30}"#;
117 let value = parse(json_str).unwrap();
118 let result = stringify(&value).unwrap();
119
120 let original: serde_json::Value = serde_json::from_str(json_str).unwrap();
122 let parsed: serde_json::Value = serde_json::from_str(&result).unwrap();
123 assert_eq!(original, parsed);
124 }
125
126 #[test]
127 fn test_constructors() {
128 assert_eq!(null(), Value::Null);
129 assert_eq!(boolean(true), Value::Bool(true));
130 assert_eq!(string("test"), Value::String("test".to_string()));
131 assert!(matches!(number_i64(42), Value::Number(_)));
132 }
133
134 #[test]
135 fn test_pretty_print() {
136 let value = parse(r#"{"a":1,"b":2}"#).unwrap();
137 let pretty = stringify_pretty(&value).unwrap();
138 assert!(pretty.contains('\n'));
139 assert!(pretty.contains(" "));
140 }
141
142 #[test]
143 fn test_get() {
144 let json = r#"{"name": "Alice", "age": 30, "active": true}"#;
145 let value = parse(json).unwrap();
146
147 assert!(get(&value, "name").is_some());
148 assert_eq!(get_string(&value, "name"), Some("Alice".to_string()));
149 assert_eq!(get_number(&value, "age"), Some(30.0));
150 assert_eq!(get_bool(&value, "active"), Some(true));
151 }
152
153 #[test]
154 fn test_set() {
155 let json = r#"{"name": "Alice"}"#;
156 let mut value = parse(json).unwrap();
157
158 let new_name = string("Bob");
159 let result = set(&mut value, "name", new_name);
160 assert!(result.is_ok());
161 assert_eq!(get_string(&value, "name"), Some("Bob".to_string()));
162 }
163
164 #[test]
165 fn test_len_is_empty() {
166 let json_array = r#"[1, 2, 3, 4, 5]"#;
167 let value_array = parse(json_array).unwrap();
168 assert_eq!(len(&value_array), 5);
169 assert!(!is_empty(&value_array));
170
171 let json_object = r#"{"a": 1, "b": 2}"#;
172 let value_object = parse(json_object).unwrap();
173 assert_eq!(len(&value_object), 2);
174 assert!(!is_empty(&value_object));
175
176 let empty_array = array();
177 assert_eq!(len(&empty_array), 0);
178 assert!(is_empty(&empty_array));
179 }
180}