neon/object/
class.rs

1use crate::{
2    context::Cx,
3    handle::{Handle, Root},
4    object::Object,
5    result::{JsResult, NeonResult},
6    types::JsFunction,
7};
8
9#[doc(hidden)]
10pub trait ClassInternal {
11    fn local<'cx>(cx: &mut Cx<'cx>) -> NeonResult<ClassMetadata<'cx>>;
12    fn create<'cx>(cx: &mut Cx<'cx>) -> NeonResult<ClassMetadata<'cx>>;
13}
14
15/// A trait defining a Neon class.
16///
17/// **This should not be implemented directly.** Instead, use the [`#[neon::class]`](crate::class)
18/// attribute macro to define a class, which will automatically implement this trait.
19pub trait Class: ClassInternal {
20    /// The class name.
21    fn name() -> String;
22
23    /// The constructor function for the class.
24    fn constructor<'cx>(cx: &mut Cx<'cx>) -> JsResult<'cx, JsFunction>;
25}
26
27#[doc(hidden)]
28pub struct ClassMetadata<'cx> {
29    external_constructor: Handle<'cx, JsFunction>,
30    internal_constructor: Handle<'cx, JsFunction>,
31}
32
33pub fn new_class_metadata<'cx>(
34    external: Handle<'cx, JsFunction>,
35    internal: Handle<'cx, JsFunction>,
36) -> ClassMetadata<'cx> {
37    ClassMetadata {
38        external_constructor: external,
39        internal_constructor: internal,
40    }
41}
42
43impl<'cx> ClassMetadata<'cx> {
44    pub fn constructor(&self) -> Handle<'cx, JsFunction> {
45        self.external_constructor
46    }
47
48    pub(crate) fn internal_constructor(&self) -> Handle<'cx, JsFunction> {
49        self.internal_constructor
50    }
51
52    #[doc(hidden)]
53    pub fn root<'cx2>(&self, cx: &mut Cx<'cx2>) -> RootClassMetadata {
54        RootClassMetadata {
55            external_constructor: self.external_constructor.root(cx),
56            internal_constructor: self.internal_constructor.root(cx),
57        }
58    }
59}
60
61#[doc(hidden)]
62pub struct RootClassMetadata {
63    pub external_constructor: Root<JsFunction>,
64    pub internal_constructor: Root<JsFunction>,
65}
66
67// Since it's just a pair of Root which are both Send, we can mark it as such.
68unsafe impl Send for RootClassMetadata {}
69
70impl RootClassMetadata {
71    pub fn to_inner<'a, 'cx: 'a>(&'a self, cx: &'a mut Cx<'cx>) -> ClassMetadata<'cx> {
72        ClassMetadata {
73            external_constructor: self.external_constructor.to_inner(cx),
74            internal_constructor: self.internal_constructor.to_inner(cx),
75        }
76    }
77}