neon/types_impl/extract/
try_into_js.rs

1use crate::{
2    context::{Context, Cx},
3    handle::{Handle, Root},
4    object::Object,
5    result::{JsResult, Throw},
6    types::{extract::TryIntoJs, JsBoolean, JsNumber, JsString, JsUndefined, JsValue, Value},
7};
8
9#[cfg(feature = "napi-5")]
10use crate::{
11    result::ResultExt,
12    types::{extract::Date, JsDate},
13};
14
15impl<'cx, T> TryIntoJs<'cx> for Handle<'cx, T>
16where
17    T: Value,
18{
19    type Value = T;
20
21    fn try_into_js(self, _cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
22        Ok(self)
23    }
24}
25
26impl<'cx, O> TryIntoJs<'cx> for Root<O>
27where
28    O: Object,
29{
30    type Value = O;
31
32    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
33        Ok(self.into_inner(cx))
34    }
35}
36
37impl<'cx, T, E> TryIntoJs<'cx> for Result<T, E>
38where
39    T: TryIntoJs<'cx>,
40    E: TryIntoJs<'cx>,
41{
42    type Value = T::Value;
43
44    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
45        match self {
46            Ok(v) => v.try_into_js(cx),
47            Err(err) => {
48                let err = err.try_into_js(cx)?;
49
50                cx.throw(err)
51            }
52        }
53    }
54}
55
56impl<'cx> TryIntoJs<'cx> for Throw {
57    type Value = JsValue;
58
59    fn try_into_js(self, _cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
60        Err(self)
61    }
62}
63
64impl<'cx, T> TryIntoJs<'cx> for Option<T>
65where
66    T: TryIntoJs<'cx>,
67{
68    type Value = JsValue;
69
70    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
71        if let Some(val) = self {
72            val.try_into_js(cx).map(|v| v.upcast())
73        } else {
74            Ok(cx.undefined().upcast())
75        }
76    }
77}
78
79impl<'cx, T> TryIntoJs<'cx> for Box<T>
80where
81    T: TryIntoJs<'cx>,
82{
83    type Value = T::Value;
84
85    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
86        (*self).try_into_js(cx)
87    }
88}
89
90macro_rules! impl_number {
91    ($ty:ident) => {
92        impl<'cx> TryIntoJs<'cx> for $ty {
93            type Value = JsNumber;
94
95            fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
96                Ok(cx.number(self))
97            }
98        }
99    };
100
101    ($($ty:ident),* $(,)?) => {
102        $(
103            impl_number!($ty);
104        )*
105    }
106}
107
108impl_number!(u8, u16, u32, i8, i16, i32, f32, f64);
109
110impl<'cx> TryIntoJs<'cx> for String {
111    type Value = JsString;
112
113    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
114        Ok(cx.string(self))
115    }
116}
117
118impl<'a, 'cx> TryIntoJs<'cx> for &'a str {
119    type Value = JsString;
120
121    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
122        Ok(cx.string(self))
123    }
124}
125
126impl<'a, 'cx> TryIntoJs<'cx> for &'a String {
127    type Value = JsString;
128
129    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
130        Ok(cx.string(self))
131    }
132}
133
134impl<'cx> TryIntoJs<'cx> for bool {
135    type Value = JsBoolean;
136
137    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
138        Ok(cx.boolean(self))
139    }
140}
141
142impl<'cx> TryIntoJs<'cx> for () {
143    type Value = JsUndefined;
144
145    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
146        Ok(cx.undefined())
147    }
148}
149
150#[cfg(feature = "napi-5")]
151impl<'cx> TryIntoJs<'cx> for Date {
152    type Value = JsDate;
153
154    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
155        cx.date(self.0).or_throw(cx)
156    }
157}