napi/bindgen_runtime/js_values/
number.rs

1use crate::{bindgen_prelude::ToNapiValue, check_status, sys, type_of, Error, Result};
2
3macro_rules! impl_number_conversions {
4  ( $( ($name:literal, $t:ty as $st:ty, $get:ident, $create:ident) ,)* ) => {
5    $(
6      impl $crate::bindgen_prelude::TypeName for $t {
7        fn type_name() -> &'static str {
8          $name
9        }
10
11        fn value_type() -> crate::ValueType {
12          crate::ValueType::Number
13        }
14      }
15
16      impl $crate::bindgen_prelude::ValidateNapiValue for $t { }
17
18      impl ToNapiValue for $t {
19        unsafe fn to_napi_value(env: $crate::sys::napi_env, val: $t) -> Result<$crate::sys::napi_value> {
20          let mut ptr = std::ptr::null_mut();
21          let val: $st = val.into();
22
23          check_status!(
24            unsafe { sys::$create(env, val, &mut ptr) },
25            "Failed to convert rust type `{}` into napi value",
26            $name,
27          )?;
28
29          Ok(ptr)
30        }
31      }
32
33      impl ToNapiValue for &$t {
34        unsafe fn to_napi_value(env: $crate::sys::napi_env, val: &$t) -> Result<$crate::sys::napi_value> {
35          ToNapiValue::to_napi_value(env, *val)
36        }
37      }
38
39      impl ToNapiValue for &mut $t {
40        unsafe fn to_napi_value(env: $crate::sys::napi_env, val: &mut $t) -> Result<$crate::sys::napi_value> {
41          ToNapiValue::to_napi_value(env, *val)
42        }
43      }
44
45      impl $crate::bindgen_prelude::FromNapiValue for $t {
46        unsafe fn from_napi_value(env: $crate::sys::napi_env, napi_val: $crate::sys::napi_value) -> Result<Self> {
47          let mut ret = 0 as $st;
48
49          check_status!(
50            unsafe { sys::$get(env, napi_val, &mut ret) },
51            "Failed to convert napi value {:?} into rust type `{}`",
52            type_of!(env, napi_val)?,
53            $name,
54          )?;
55
56          ret.try_into().map_err(|_| Error::from_reason(concat!("Failed to convert ", stringify!($st), " to ", stringify!($t))))
57        }
58      }
59    )*
60  };
61}
62
63impl_number_conversions!(
64  ("u8", u8 as u32, napi_get_value_uint32, napi_create_uint32),
65  ("i8", i8 as i32, napi_get_value_int32, napi_create_int32),
66  ("u16", u16 as u32, napi_get_value_uint32, napi_create_uint32),
67  ("i16", i16 as i32, napi_get_value_int32, napi_create_int32),
68  ("u32", u32 as u32, napi_get_value_uint32, napi_create_uint32),
69  ("i32", i32 as i32, napi_get_value_int32, napi_create_int32),
70  ("i64", i64 as i64, napi_get_value_int64, napi_create_int64),
71  ("f64", f64 as f64, napi_get_value_double, napi_create_double),
72);
73
74impl ToNapiValue for f32 {
75  unsafe fn to_napi_value(env: crate::sys::napi_env, val: f32) -> Result<crate::sys::napi_value> {
76    let mut ptr = std::ptr::null_mut();
77
78    check_status!(
79      unsafe { sys::napi_create_double(env, val.into(), &mut ptr) },
80      "Failed to convert rust type `f32` into napi value",
81    )?;
82
83    Ok(ptr)
84  }
85}