neon/types_impl/extract/
container.rs

1use std::{
2    cell::{Ref, RefCell, RefMut},
3    rc::Rc,
4    sync::Arc,
5};
6
7use crate::{
8    context::{Context, Cx},
9    handle::Handle,
10    result::{JsResult, NeonResult},
11    types::{
12        extract::{TryFromJs, TryIntoJs},
13        JsBox, JsValue,
14    },
15};
16
17use super::error::TypeExpected;
18
19impl<'cx, T: 'static> TryFromJs<'cx> for &'cx RefCell<T> {
20    type Error = TypeExpected<JsBox<RefCell<T>>>;
21
22    fn try_from_js(
23        cx: &mut Cx<'cx>,
24        v: Handle<'cx, JsValue>,
25    ) -> NeonResult<Result<Self, Self::Error>> {
26        match v.downcast::<JsBox<RefCell<T>>, _>(cx) {
27            Ok(v) => Ok(Ok(JsBox::deref(&v))),
28            Err(_) => Ok(Err(TypeExpected::new())),
29        }
30    }
31}
32
33impl<'cx, T: 'static> TryFromJs<'cx> for Ref<'cx, T> {
34    type Error = TypeExpected<JsBox<RefCell<T>>>;
35
36    fn try_from_js(
37        cx: &mut Cx<'cx>,
38        v: Handle<'cx, JsValue>,
39    ) -> NeonResult<Result<Self, Self::Error>> {
40        match v.downcast::<JsBox<RefCell<T>>, _>(cx) {
41            Ok(v) => match JsBox::deref(&v).try_borrow() {
42                Ok(r) => Ok(Ok(r)),
43                Err(_) => cx.throw_error("RefCell is already mutably borrowed"),
44            },
45            Err(_) => Ok(Err(TypeExpected::new())),
46        }
47    }
48}
49
50impl<'cx, T: 'static> TryFromJs<'cx> for RefMut<'cx, T> {
51    type Error = TypeExpected<JsBox<RefCell<T>>>;
52
53    fn try_from_js(
54        cx: &mut Cx<'cx>,
55        v: Handle<'cx, JsValue>,
56    ) -> NeonResult<Result<Self, Self::Error>> {
57        match v.downcast::<JsBox<RefCell<T>>, _>(cx) {
58            Ok(v) => match JsBox::deref(&v).try_borrow_mut() {
59                Ok(r) => Ok(Ok(r)),
60                Err(_) => cx.throw_error("RefCell is already borrowed"),
61            },
62            Err(_) => Ok(Err(TypeExpected::new())),
63        }
64    }
65}
66
67impl<'cx, T> TryIntoJs<'cx> for RefCell<T>
68where
69    T: 'static,
70{
71    type Value = JsBox<RefCell<T>>;
72
73    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
74        Ok(JsBox::manually_finalize(cx, self))
75    }
76}
77
78impl<'cx, T: 'static> TryFromJs<'cx> for Rc<T> {
79    type Error = TypeExpected<JsBox<Rc<T>>>;
80
81    fn try_from_js(
82        cx: &mut Cx<'cx>,
83        v: Handle<'cx, JsValue>,
84    ) -> NeonResult<Result<Self, Self::Error>> {
85        match v.downcast::<JsBox<Rc<T>>, _>(cx) {
86            Ok(v) => Ok(Ok(Rc::clone(&v))),
87            Err(_) => Ok(Err(TypeExpected::new())),
88        }
89    }
90}
91
92impl<'cx, T> TryIntoJs<'cx> for Rc<T>
93where
94    T: 'static,
95{
96    type Value = JsBox<Rc<T>>;
97
98    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
99        Ok(JsBox::manually_finalize(cx, self))
100    }
101}
102
103impl<'cx, T: 'static> TryFromJs<'cx> for Arc<T> {
104    type Error = TypeExpected<JsBox<Arc<T>>>;
105
106    fn try_from_js(
107        cx: &mut Cx<'cx>,
108        v: Handle<'cx, JsValue>,
109    ) -> NeonResult<Result<Self, Self::Error>> {
110        match v.downcast::<JsBox<Arc<T>>, _>(cx) {
111            Ok(v) => Ok(Ok(Arc::clone(&v))),
112            Err(_) => Ok(Err(TypeExpected::new())),
113        }
114    }
115}
116
117impl<'cx, T> TryIntoJs<'cx> for Arc<T>
118where
119    T: 'static,
120{
121    type Value = JsBox<Arc<T>>;
122
123    fn try_into_js(self, cx: &mut Cx<'cx>) -> JsResult<'cx, Self::Value> {
124        Ok(JsBox::manually_finalize(cx, self))
125    }
126}