aether/builtins/
json.rs

1// src/builtins/json.rs
2//! JSON 处理内置函数模块
3//!
4//! 提供 JSON 解析和序列化功能。
5
6use crate::evaluator::RuntimeError;
7use crate::value::Value;
8use num_traits::ToPrimitive;
9use std::collections::HashMap;
10
11/// 将 JSON 字符串解析为 Aether 值
12///
13/// # 功能
14/// 解析 JSON 格式的字符串,转换为对应的 Aether 数据结构。
15///
16/// # 参数
17/// - `json_str`: JSON 格式的字符串
18///
19/// # 返回值
20/// 解析后的 Aether 值(Dict、Array、String、Number、Boolean 或 Null)
21///
22/// # 映射规则
23/// - JSON object → Dict
24/// - JSON array → Array
25/// - JSON string → String
26/// - JSON number → Number
27/// - JSON boolean → Boolean
28/// - JSON null → Null
29///
30/// # 示例
31/// ```aether
32/// Set JSON_STR "{\"name\":\"Alice\",\"age\":30}"
33/// Set OBJ JSON_PARSE(JSON_STR)
34/// Println(OBJ["name"])  # 输出: Alice
35/// ```
36pub fn json_parse(args: &[Value]) -> Result<Value, RuntimeError> {
37    if args.len() != 1 {
38        return Err(RuntimeError::WrongArity {
39            expected: 1,
40            got: args.len(),
41        });
42    }
43
44    let json_str = match &args[0] {
45        Value::String(s) => s,
46        other => {
47            return Err(RuntimeError::TypeErrorDetailed {
48                expected: "String".to_string(),
49                got: format!("{:?}", other),
50            })
51        }
52    };
53
54    // 使用 serde_json 解析
55    let json_value: serde_json::Value = serde_json::from_str(json_str)
56        .map_err(|e| RuntimeError::CustomError(format!("JSON parse error: {}", e)))?;
57
58    // 转换为 Aether Value
59    json_to_value(&json_value)
60}
61
62/// 将 Aether 值序列化为 JSON 字符串
63///
64/// # 功能
65/// 将 Aether 数据结构转换为 JSON 格式的字符串。
66///
67/// # 参数
68/// - `value`: 要序列化的值
69/// - `indent`: (可选)缩进空格数,默认为 0(紧凑格式)
70///
71/// # 返回值
72/// JSON 格式的字符串
73///
74/// # 示例
75/// ```aether
76/// Set OBJ {"name": "Alice", "age": 30}
77/// Set JSON_STR JSON_STRINGIFY(OBJ)
78/// Println(JSON_STR)  # 输出: {"name":"Alice","age":30}
79///
80/// # 格式化输出(2空格缩进)
81/// Set PRETTY JSON_STRINGIFY(OBJ, 2)
82/// ```
83pub fn json_stringify(args: &[Value]) -> Result<Value, RuntimeError> {
84    if args.is_empty() || args.len() > 2 {
85        return Err(RuntimeError::WrongArity {
86            expected: 1,
87            got: args.len(),
88        });
89    }
90
91    let value = &args[0];
92    let indent = if args.len() == 2 {
93        match &args[1] {
94            Value::Number(n) => *n as usize,
95            other => {
96                return Err(RuntimeError::TypeErrorDetailed {
97                    expected: "Number".to_string(),
98                    got: format!("{:?}", other),
99                })
100            }
101        }
102    } else {
103        0
104    };
105
106    // 转换为 serde_json::Value
107    let json_value = value_to_json(value)?;
108
109    // 序列化
110    let json_str = if indent > 0 {
111        serde_json::to_string_pretty(&json_value)
112    } else {
113        serde_json::to_string(&json_value)
114    }
115    .map_err(|e| RuntimeError::CustomError(format!("JSON stringify error: {}", e)))?;
116
117    Ok(Value::String(json_str))
118}
119
120/// 将 serde_json::Value 转换为 Aether Value
121fn json_to_value(json: &serde_json::Value) -> Result<Value, RuntimeError> {
122    match json {
123        serde_json::Value::Null => Ok(Value::Null),
124        serde_json::Value::Bool(b) => Ok(Value::Boolean(*b)),
125        serde_json::Value::Number(n) => {
126            if let Some(i) = n.as_i64() {
127                Ok(Value::Number(i as f64))
128            } else if let Some(u) = n.as_u64() {
129                Ok(Value::Number(u as f64))
130            } else if let Some(f) = n.as_f64() {
131                Ok(Value::Number(f))
132            } else {
133                Err(RuntimeError::CustomError("Invalid JSON number".to_string()))
134            }
135        }
136        serde_json::Value::String(s) => Ok(Value::String(s.clone())),
137        serde_json::Value::Array(arr) => {
138            let mut aether_arr = Vec::new();
139            for item in arr {
140                aether_arr.push(json_to_value(item)?);
141            }
142            Ok(Value::Array(aether_arr))
143        }
144        serde_json::Value::Object(obj) => {
145            let mut aether_dict = HashMap::new();
146            for (key, val) in obj {
147                aether_dict.insert(key.clone(), json_to_value(val)?);
148            }
149            Ok(Value::Dict(aether_dict))
150        }
151    }
152}
153
154/// 将 Aether Value 转换为 serde_json::Value
155fn value_to_json(value: &Value) -> Result<serde_json::Value, RuntimeError> {
156    match value {
157        Value::Null => Ok(serde_json::Value::Null),
158        Value::Boolean(b) => Ok(serde_json::Value::Bool(*b)),
159        Value::Number(n) => Ok(serde_json::json!(n)),
160        Value::String(s) => Ok(serde_json::Value::String(s.clone())),
161        Value::Array(arr) => {
162            let mut json_arr = Vec::new();
163            for item in arr {
164                json_arr.push(value_to_json(item)?);
165            }
166            Ok(serde_json::Value::Array(json_arr))
167        }
168        Value::Dict(dict) => {
169            let mut json_obj = serde_json::Map::new();
170            for (key, val) in dict {
171                json_obj.insert(key.clone(), value_to_json(val)?);
172            }
173            Ok(serde_json::Value::Object(json_obj))
174        }
175        Value::Fraction(f) => {
176            // 将分数转换为浮点数
177            let float_val = f.numer().to_f64().unwrap_or(0.0) / f.denom().to_f64().unwrap_or(1.0);
178            Ok(serde_json::json!(float_val))
179        }
180        other => Err(RuntimeError::CustomError(format!(
181            "Cannot convert {:?} to JSON",
182            other
183        ))),
184    }
185}