1use crate::{bindgen_prelude::*, check_status, sys, type_of, JsObject, ValueType};
2use std::{ffi::CString, ptr};
3
4pub type Object = JsObject;
5
6impl Object {
7 #[cfg(feature = "serde-json")]
8 pub(crate) fn new(env: sys::napi_env) -> Result<Self> {
9 let mut ptr = ptr::null_mut();
10 unsafe {
11 check_status!(
12 sys::napi_create_object(env, &mut ptr),
13 "Failed to create napi Object"
14 )?;
15 }
16
17 Ok(Self(crate::Value {
18 env,
19 value: ptr,
20 value_type: ValueType::Object,
21 }))
22 }
23
24 pub fn get<K: AsRef<str>, V: FromNapiValue>(&self, field: K) -> Result<Option<V>> {
25 let c_field = CString::new(field.as_ref())?;
26
27 unsafe {
28 let mut ret = ptr::null_mut();
29
30 check_status!(
31 sys::napi_get_named_property(self.0.env, self.0.value, c_field.as_ptr(), &mut ret),
32 "Failed to get property with field `{}`",
33 field.as_ref(),
34 )?;
35
36 let ty = type_of!(self.0.env, ret)?;
37
38 Ok(if ty == ValueType::Undefined {
39 None
40 } else {
41 Some(V::from_napi_value(self.0.env, ret)?)
42 })
43 }
44 }
45
46 pub fn set<K: AsRef<str>, V: ToNapiValue>(&mut self, field: K, val: V) -> Result<()> {
47 let c_field = CString::new(field.as_ref())?;
48
49 unsafe {
50 let napi_val = V::to_napi_value(self.0.env, val)?;
51
52 check_status!(
53 sys::napi_set_named_property(self.0.env, self.0.value, c_field.as_ptr(), napi_val),
54 "Failed to set property with field `{}`",
55 c_field.to_string_lossy(),
56 )?;
57
58 Ok(())
59 }
60 }
61
62 pub fn keys(obj: &Object) -> Result<Vec<String>> {
63 let mut names = ptr::null_mut();
64 unsafe {
65 check_status!(
66 sys::napi_get_property_names(obj.0.env, obj.0.value, &mut names),
67 "Failed to get property names of given object"
68 )?;
69 }
70
71 let names = unsafe { Array::from_napi_value(obj.0.env, names)? };
72 let mut ret = vec![];
73
74 for i in 0..names.len() {
75 ret.push(names.get::<String>(i)?.unwrap());
76 }
77
78 Ok(ret)
79 }
80}
81
82impl TypeName for Object {
83 fn type_name() -> &'static str {
84 "Object"
85 }
86
87 fn value_type() -> ValueType {
88 ValueType::Object
89 }
90}
91
92impl ValidateNapiValue for JsObject {}
93