Skip to main content

pipa/host/
value.rs

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}