use crate::lua_value::LuaValue;
use crate::lua_vm::GlobalState;
use serde_json::Value as JsonValue;
pub fn from_value(json_value: &JsonValue, gs: &mut GlobalState) -> Result<LuaValue, String> {
match json_value {
JsonValue::Null => Ok(LuaValue::nil()),
JsonValue::Bool(b) => Ok(LuaValue::boolean(*b)),
JsonValue::Number(n) => {
if let Some(i) = n.as_i64() {
Ok(LuaValue::number(i as f64))
} else if let Some(u) = n.as_u64() {
Ok(LuaValue::number(u as f64))
} else if let Some(f) = n.as_f64() {
Ok(LuaValue::number(f))
} else {
Err("Invalid JSON number".to_string())
}
}
JsonValue::String(s) => gs
.create_string(s)
.map_err(|e| format!("Failed to create string: {}", e)),
JsonValue::Array(arr) => json_array_to_lua_table(arr, gs),
JsonValue::Object(obj) => json_object_to_lua_table(obj, gs),
}
}
pub fn from_str(json_str: &str, gs: &mut GlobalState) -> Result<LuaValue, String> {
let json_value: JsonValue =
serde_json::from_str(json_str).map_err(|e| format!("Failed to parse JSON: {}", e))?;
from_value(&json_value, gs)
}
fn json_array_to_lua_table(arr: &[JsonValue], gs: &mut GlobalState) -> Result<LuaValue, String> {
let table = gs
.create_table(arr.len(), 0)
.map_err(|e| format!("Failed to create table: {}", e))?;
for (i, item) in arr.iter().enumerate() {
let value = from_value(item, gs)?;
let key = LuaValue::number((i + 1) as f64);
gs.raw_set(&table, key, value);
}
Ok(table)
}
fn json_object_to_lua_table(
obj: &serde_json::Map<String, JsonValue>,
gs: &mut GlobalState,
) -> Result<LuaValue, String> {
let table = gs
.create_table(0, obj.len())
.map_err(|e| format!("Failed to create table: {}", e))?;
for (key_str, value_json) in obj {
let key = gs
.create_string(key_str)
.map_err(|e| format!("Failed to create key string: {}", e))?;
let value = from_value(value_json, gs)?;
gs.raw_set(&table, key, value);
}
Ok(table)
}