use roto::{Runtime, Val, roto_method, roto_static_method};
use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
use crate::means_of_production::{Error, MutableStringList};
#[derive(Debug, Clone, Default)]
pub struct Json(Rc<RefCell<serde_json::Value>>);
pub fn register_json(runtime: &mut Runtime) -> Result<(), Error> {
runtime.register_clone_type_with_name::<Json>("Json", "A JSON value")?;
{
#[roto_static_method(runtime, Json)]
fn load_file(path: Arc<str>) -> Val<Json> {
let data = std::fs::read_to_string(path.as_ref()).unwrap_or_else(|e| {
tracing::error!({ file = path.to_string() }, "Error loading JSON file: {e}");
String::from("{}")
});
let json = serde_json::from_str(&data).unwrap_or_else(|e| {
tracing::error!({ data }, "Error parsing JSON data: {e}");
serde_json::from_str("{}").unwrap()
});
Json(Rc::new(RefCell::new(json))).into()
}
}
#[roto_method(runtime, Json)]
fn get_keys(json: Val<Json>) -> Val<MutableStringList> {
match &*(*json).0.borrow() {
serde_json::Value::Object(obj) => {
MutableStringList(Rc::new(RefCell::new(obj.keys().cloned().collect())))
}
value => {
tracing::warn!({ value = value.to_string() }, "JSON value is not an object");
MutableStringList::default()
}
}
.into()
}
Ok(())
}