///|
#borrow(result)
extern "c" fn napi_keys_raw(
env : NapiEnv,
value : NapiValue,
result : Ref[NapiValue],
) -> Int32 = "moonbit_napi_keys"
///|
#borrow(result)
extern "c" fn napi_key_get_raw(
env : NapiEnv,
value : NapiValue,
key : NapiValue,
result : Ref[NapiValue],
) -> Int32 = "napi_get_property"
///|
extern "c" fn napi_key_set_raw(
env : NapiEnv,
value : NapiValue,
key : NapiValue,
field : NapiValue,
) -> Int32 = "moonbit_napi_key_set"
///|
#borrow(result)
extern "c" fn napi_is_array_raw(
env : NapiEnv,
value : NapiValue,
result : Ref[Bool],
) -> Int32 = "moonbit_napi_is_array"
///|
pub fn napi_object_keys(
env : NapiEnv,
value : NapiValue,
) -> Array[String] raise NapiError {
let result = Ref(moonbit_dummy_napi_value())
result_from_status(
env,
napi_keys_raw(env, value, result),
b"Reading own enumerable string keys",
)
Array::makei(napi_array_length(env, result.val), i => {
get_String(env, napi_array_get(env, result.val, i))
})
}
///|
pub fn napi_key_get(
env : NapiEnv,
value : NapiValue,
key : String,
) -> NapiValue raise NapiError {
let result = Ref(moonbit_dummy_napi_value())
result_from_status(
env,
napi_key_get_raw(env, value, set_String(env, key), result),
b"Reading record property",
)
result.val
}
///|
pub fn napi_key_set(
env : NapiEnv,
value : NapiValue,
key : String,
field : NapiValue,
) -> Unit raise NapiError {
result_from_status(
env,
napi_key_set_raw(env, value, set_String(env, key), field),
b"Writing record property",
)
}
///|
pub fn napi_read_json(
env : NapiEnv,
value : NapiValue,
path : Array[NapiValue],
) -> Json raise NapiError {
let kind = Ref(0)
result_from_status(
env,
napi_value_kind(env, value, kind),
b"Reading JSON kind",
)
match kind.val {
1 => Json::null()
2 => Json(get_Bool(env, value))
3 => {
let number = get_Double(env, value)
if number.is_nan() || number.is_inf() {
raise napi_failure(
1,
TypeError,
"ERR_NAPI_JSON",
"JSON numbers must be finite",
)
}
Json(number)
}
4 => Json(get_String(env, value))
6 => {
napi_enter_value(env, value, path)
defer ignore(path.pop())
let array = Ref(false)
result_from_status(
env,
napi_is_array_raw(env, value, array),
b"Reading JSON array",
)
if array.val {
Json::array(
Array::makei(napi_array_length(env, value), i => {
napi_read_json(env, napi_array_get(env, value, i), path)
}),
)
} else {
let fields : Map[String, Json] = Map([])
for key in napi_object_keys(env, value) {
fields[key] = napi_read_json(env, napi_key_get(env, value, key), path)
}
Json::object(fields)
}
}
_ =>
raise napi_failure(1, TypeError, "ERR_NAPI_JSON", "Expected a JSON value")
}
}
///|
pub fn napi_write_json(
env : NapiEnv,
value : Json,
depth : Int32,
) -> NapiValue raise NapiError {
napi_check_depth(depth)
match value {
Null => napi_null(env)
True => set_Bool(env, true)
False => set_Bool(env, false)
String(text) => set_String(env, text)
Number(number, ..) => {
if number.is_nan() || number.is_inf() {
raise napi_failure(
1,
TypeError,
"ERR_NAPI_JSON",
"JSON numbers must be finite",
)
}
set_Double(env, number)
}
Array(items) => {
let result = napi_array_new(env, items.length())
for i, item in items {
napi_array_set(env, result, i, napi_write_json(env, item, depth + 1))
}
result
}
Object(fields) => {
let result = napi_object_new(env)
for key, item in fields {
napi_key_set(env, result, key, napi_write_json(env, item, depth + 1))
}
result
}
}
}