napi_h/bindgen_runtime/js_values/
object.rs

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 {}