1use crate::runtime::context::JSContext;
2use crate::value::JSValue;
3
4pub trait ToJS {
5 fn to_js(&self, ctx: &mut JSContext) -> JSValue;
6}
7
8pub trait FromJS: Sized {
9 fn from_js(value: &JSValue, ctx: &JSContext) -> Option<Self>;
10}
11
12impl ToJS for () {
13 fn to_js(&self, _ctx: &mut JSContext) -> JSValue {
14 JSValue::undefined()
15 }
16}
17
18impl ToJS for bool {
19 fn to_js(&self, _ctx: &mut JSContext) -> JSValue {
20 JSValue::bool(*self)
21 }
22}
23
24impl ToJS for i32 {
25 fn to_js(&self, _ctx: &mut JSContext) -> JSValue {
26 JSValue::new_int(*self as i64)
27 }
28}
29
30impl ToJS for i64 {
31 fn to_js(&self, _ctx: &mut JSContext) -> JSValue {
32 JSValue::new_int(*self)
33 }
34}
35
36impl ToJS for f64 {
37 fn to_js(&self, _ctx: &mut JSContext) -> JSValue {
38 JSValue::new_float(*self)
39 }
40}
41
42impl ToJS for String {
43 fn to_js(&self, ctx: &mut JSContext) -> JSValue {
44 JSValue::new_string(ctx.intern(self))
45 }
46}
47
48impl ToJS for &str {
49 fn to_js(&self, ctx: &mut JSContext) -> JSValue {
50 JSValue::new_string(ctx.intern(self))
51 }
52}
53
54impl<T: ToJS> ToJS for Option<T> {
55 fn to_js(&self, ctx: &mut JSContext) -> JSValue {
56 match self {
57 Some(v) => v.to_js(ctx),
58 None => JSValue::null(),
59 }
60 }
61}
62
63impl FromJS for () {
64 fn from_js(_value: &JSValue, _ctx: &JSContext) -> Option<Self> {
65 Some(())
66 }
67}
68
69impl FromJS for bool {
70 fn from_js(value: &JSValue, _ctx: &JSContext) -> Option<Self> {
71 if value.is_bool() {
72 Some(value.get_bool())
73 } else {
74 None
75 }
76 }
77}
78
79impl FromJS for i32 {
80 fn from_js(value: &JSValue, _ctx: &JSContext) -> Option<Self> {
81 if value.is_int() {
82 Some(value.get_int() as i32)
83 } else {
84 None
85 }
86 }
87}
88
89impl FromJS for i64 {
90 fn from_js(value: &JSValue, _ctx: &JSContext) -> Option<Self> {
91 if value.is_int() {
92 Some(value.get_int())
93 } else {
94 None
95 }
96 }
97}
98
99impl FromJS for f64 {
100 fn from_js(value: &JSValue, _ctx: &JSContext) -> Option<Self> {
101 if value.is_int() {
102 Some(value.get_int() as f64)
103 } else if value.is_float() {
104 Some(value.get_float())
105 } else {
106 None
107 }
108 }
109}
110
111impl FromJS for String {
112 fn from_js(value: &JSValue, ctx: &JSContext) -> Option<Self> {
113 if value.is_string() {
114 let atom = value.get_atom();
115 Some(ctx.get_atom_str(atom).to_string())
116 } else {
117 None
118 }
119 }
120}