use crate::quickjs_utils;
use crate::quickjsrealmadapter::QuickJsRealmAdapter;
use crate::valueref::JSValueRef;
use hirofa_utils::js_utils::JsError;
use libquickjs_sys as q;
use std::ffi::CString;
pub fn parse_q(q_ctx: &QuickJsRealmAdapter, input: &str) -> Result<JSValueRef, JsError> {
unsafe { parse(q_ctx.context, input) }
}
pub unsafe fn parse(context: *mut q::JSContext, input: &str) -> Result<JSValueRef, JsError> {
let s = CString::new(input).ok().unwrap();
let f_n = CString::new("JSON.parse").ok().unwrap();
let len = input.len();
let val = q::JS_ParseJSON(context, s.as_ptr(), len as _, f_n.as_ptr());
let ret = JSValueRef::new(context, val, false, true, "json::parse result");
if ret.is_exception() {
if let Some(ex) = QuickJsRealmAdapter::get_exception(context) {
Err(ex)
} else {
Err(JsError::new_str("unknown error while parsing json"))
}
} else {
Ok(ret)
}
}
pub fn stringify_q(
q_ctx: &QuickJsRealmAdapter,
input: &JSValueRef,
opt_space: Option<JSValueRef>,
) -> Result<JSValueRef, JsError> {
unsafe { stringify(q_ctx.context, input, opt_space) }
}
pub unsafe fn stringify(
context: *mut q::JSContext,
input: &JSValueRef,
opt_space: Option<JSValueRef>,
) -> Result<JSValueRef, JsError> {
let space_ref = match opt_space {
None => quickjs_utils::new_null_ref(),
Some(s) => s,
};
let val = q::JS_JSONStringify(
context,
*input.borrow_value(),
quickjs_utils::new_null(),
*space_ref.borrow_value(),
);
let ret = JSValueRef::new(context, val, false, true, "json::stringify result");
if ret.is_exception() {
if let Some(ex) = QuickJsRealmAdapter::get_exception(context) {
Err(ex)
} else {
Err(JsError::new_str("unknown error in json::stringify"))
}
} else {
Ok(ret)
}
}
#[cfg(test)]
pub mod tests {
use crate::facades::tests::init_test_rt;
use crate::quickjs_utils::{json, objects, primitives};
#[test]
fn test_json() {
let rt = init_test_rt();
rt.exe_rt_task_in_event_loop(|q_js_rt| {
let q_ctx = q_js_rt.get_main_context();
let obj = objects::create_object_q(q_ctx).ok().unwrap();
objects::set_property_q(q_ctx, &obj, "a", &primitives::from_i32(532))
.ok()
.unwrap();
objects::set_property_q(q_ctx, &obj, "b", &primitives::from_bool(true))
.ok()
.unwrap();
objects::set_property_q(
q_ctx,
&obj,
"c",
&primitives::from_string_q(q_ctx, "abc").ok().unwrap(),
)
.ok()
.unwrap();
let str_res = json::stringify_q(q_ctx, &obj, None).ok().unwrap();
assert_eq!(str_res.get_ref_count(), 1);
let json = primitives::to_string_q(q_ctx, &str_res).ok().unwrap();
assert_eq!(json.as_str(), "{\"a\":532,\"b\":true,\"c\":\"abc\"}");
let obj2 = json::parse_q(q_ctx, json.as_str()).ok().unwrap();
assert_eq!(
532,
primitives::to_i32(&objects::get_property_q(q_ctx, &obj2, "a").ok().unwrap())
.ok()
.unwrap()
);
});
}
}