kg_js/
de.rs

1use super::*;
2use serde::de::*;
3
4
5impl<'de, T: Deserialize<'de>> ReadJs for T {
6    fn read_js(ctx: &DukContext, obj_index: i32) -> Result<Self, JsError> {
7        Self::deserialize(JsEngineDeserializer::new(ctx, obj_index))
8    }
9}
10
11pub struct JsEngineDeserializer<'a> {
12    ctx: &'a DukContext,
13    index: i32,
14    len: usize,
15}
16
17impl <'a> JsEngineDeserializer<'a> {
18    pub fn new(ctx: &'a DukContext, index: i32) -> Self {
19        Self { ctx, index, len: 0 }
20    }
21}
22
23impl<'de, 'a> Deserializer<'de> for JsEngineDeserializer<'a> {
24    type Error = JsError;
25
26    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
27        use super::DukType::*;
28
29        match self.ctx.get_type(self.index) {
30            DUK_TYPE_UNDEFINED | DUK_TYPE_NULL => visitor.visit_none(),
31            DUK_TYPE_BOOLEAN => visitor.visit_bool(self.ctx.get_boolean(self.index)),
32            DUK_TYPE_NUMBER => {
33                let n = self.ctx.get_number(self.index);
34                if n.is_finite() && (n.trunc() - n).abs() < f64::EPSILON {
35                    visitor.visit_i64(n as i64)
36                } else {
37                    visitor.visit_f64(n)
38                }
39            }
40            DUK_TYPE_STRING => visitor.visit_str(self.ctx.get_string(self.index)),
41            DUK_TYPE_BUFFER => visitor.visit_bytes(self.ctx.get_buffer(self.index)),
42            DUK_TYPE_OBJECT => {
43                if self.ctx.is_array(self.index) {
44                    let len = self.ctx.get_length( self.index);
45                    self.ctx.enum_indices(self.index);
46                    let res = visitor.visit_seq(JsEngineDeserializer { ctx: self.ctx, index: -1, len });
47                    self.ctx.pop();
48                    res
49                } else if self.ctx.is_pure_object(self.index) {
50                    self.ctx.enum_keys(self.index);
51                    let res = visitor.visit_map(JsEngineDeserializer { ctx: self.ctx, index: -1, len: 0 });
52                    self.ctx.pop();
53                    res
54                } else {
55                    return Err(JsError::from(format!("Unimplemented javascript object type"))); //FIXME (jc)
56                }
57            }
58            _ => return Err(JsError::from(format!("Unimplemented javascript object type"))) //FIXME (jc),
59        }
60    }
61
62    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
63        self.deserialize_any(visitor)
64    }
65
66    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
67        self.deserialize_any(visitor)
68    }
69
70    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
71        self.deserialize_any(visitor)
72    }
73
74    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
75        self.deserialize_any(visitor)
76    }
77
78    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
79        self.deserialize_any(visitor)
80    }
81
82    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
83        self.deserialize_any(visitor)
84    }
85
86    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
87        self.deserialize_any(visitor)
88    }
89
90    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
91        self.deserialize_any(visitor)
92    }
93
94    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
95        self.deserialize_any(visitor)
96    }
97
98    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
99        self.deserialize_any(visitor)
100    }
101
102    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
103        self.deserialize_any(visitor)
104    }
105
106    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
107        self.deserialize_any(visitor)
108    }
109
110    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
111        self.deserialize_any(visitor)
112    }
113
114    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
115        self.deserialize_any(visitor)
116    }
117
118    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
119        self.deserialize_any(visitor)
120    }
121
122    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
123        self.deserialize_any(visitor)
124    }
125
126    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
127        use super::DukType::{DUK_TYPE_NULL, DUK_TYPE_UNDEFINED};
128
129        match self.ctx.get_type(self.index) {
130            DUK_TYPE_UNDEFINED | DUK_TYPE_NULL => visitor.visit_none(),
131            _ => visitor.visit_some(self)
132        }
133    }
134
135    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
136        visitor.visit_unit()
137    }
138
139    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
140        self.deserialize_any(visitor)
141    }
142
143    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
144        self.deserialize_any(visitor)
145    }
146
147    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
148        self.deserialize_any(visitor)
149    }
150
151    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
152        self.deserialize_any(visitor)
153    }
154
155    fn deserialize_tuple_struct<V>(self, _name: &'static str, _len: usize, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
156        self.deserialize_any(visitor)
157    }
158
159    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
160        self.deserialize_any(visitor)
161    }
162
163    fn deserialize_struct<V>(self, _name: &'static str, _fields: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
164        self.deserialize_any(visitor)
165    }
166
167    fn deserialize_enum<V>(self, _name: &'static str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
168        self.deserialize_any(visitor)
169    }
170
171    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
172        self.deserialize_any(visitor)
173    }
174
175    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor<'de> {
176        self.deserialize_any(visitor)
177    }
178}
179
180impl<'de, 'a> MapAccess<'de> for JsEngineDeserializer<'a> {
181    type Error = JsError;
182
183    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> where K: DeserializeSeed<'de> {
184        if self.ctx.next(-1) {
185            Ok(Some(seed.deserialize(JsEngineDeserializer { ctx: self.ctx, index: -2, len: 0 })?))
186        } else {
187            Ok(None)
188        }
189    }
190
191    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> where V: DeserializeSeed<'de> {
192        let res = seed.deserialize(JsEngineDeserializer { ctx: self.ctx, index: -1, len: 0 });
193        self.ctx.pop_n(2);
194        res
195    }
196
197    fn next_entry_seed<K, V>(&mut self, kseed: K, vseed: V) -> Result<Option<(K::Value, V::Value)>, Self::Error> where K: DeserializeSeed<'de>, V: DeserializeSeed<'de> {
198        if self.ctx.next(-1) {
199            let k = kseed.deserialize(JsEngineDeserializer { ctx: self.ctx, index: -2, len: 0 })?;
200            let v = vseed.deserialize(JsEngineDeserializer { ctx: self.ctx, index: -1, len: 0 })?;
201            self.ctx.pop_n(2);
202            Ok(Some((k, v)))
203        } else {
204            Ok(None)
205        }
206    }
207}
208
209impl<'de, 'a> SeqAccess<'de> for JsEngineDeserializer<'a> {
210    type Error = JsError;
211
212    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> where T: DeserializeSeed<'de> {
213        if self.ctx.next(-1) {
214            let v = seed.deserialize(JsEngineDeserializer { ctx: self.ctx, index: -1, len: 0 })?;
215            self.ctx.pop_n(2);
216            Ok(Some(v))
217        } else {
218            Ok(None)
219        }
220    }
221
222    fn size_hint(&self) -> Option<usize> {
223        Some(self.len)
224    }
225}
226
227
228#[cfg(test)]
229mod tests {
230    use super::*;
231    use smart_default::SmartDefault;
232    use serde::{Serialize, Deserialize};
233
234    fn deserialize<'a, T: std::fmt::Debug + Serialize + Deserialize<'a> + Default>(value: &T) {
235        let e = JsEngine::new().unwrap();
236        e.write(value).unwrap_or_else(|err| {
237            panic!("{}", err);
238        });
239        e.put_global_string("value");
240        e.get_global_string("value");
241        let val: T = e.read_top().unwrap_or_else(|err| {
242            panic!("{}", err);
243        });
244        assert_eq!(format!("{:?}", value), format!("{:?}", val));
245    }
246
247    fn deserialize_expr<'a, T: std::fmt::Debug + Deserialize<'a>>(expr: &str) -> T {
248        let e = JsEngine::new().unwrap();
249        e.eval(expr).unwrap();
250        e.get_global_string("value");
251        let val: T = e.read_top().unwrap_or_else(|err| {
252            panic!("{}", err);
253        });
254        val
255    }
256
257    fn test_deserialize<'a, T: std::fmt::Debug + Serialize + Deserialize<'a> + Default>(value: &T) {
258        deserialize(value);
259    }
260
261    #[derive(Debug, SmartDefault, Serialize, Deserialize)]
262    struct TestStruct {
263        #[default = "string value"]
264        string_field: String,
265        #[default = 'A']
266        char_field: char,
267        #[default = 1]
268        i8_field: i8,
269        #[default(_code = "vec![1.0,2.0,3.0,7.5]")]
270        arr_field: Vec<f64>,
271        optional1: Option<f64>,
272        optional2: Option<f64>,
273        unit: ()
274    }
275
276    #[test]
277    fn read_struct() {
278        let mut p = TestStruct::default();
279        p.char_field = 'B';
280        p.i8_field = 44;
281        p.optional1 = Some(3.14);
282        test_deserialize(&p);
283    }
284
285    #[test]
286    fn deserialize_zero() {
287        #[derive(Debug, Deserialize)]
288        struct TestStruct {
289            float_field: f64,
290            int_field: i64,
291        }
292
293        //language=JavaScript
294        let val: TestStruct = deserialize_expr(r#"
295    value = {
296        float_field: 0,
297        int_field: 0
298    };
299"#);
300        assert_eq!(val.float_field, 0.0);
301        assert_eq!(val.int_field, 0);
302    }
303
304    #[test]
305    fn deserialize_nan() {
306        #[derive(Debug, Deserialize)]
307        struct TestStruct {
308            float_field: f64,
309        }
310
311        //language=JavaScript
312        let val: TestStruct = deserialize_expr(r#"
313    value = {
314        float_field: NaN
315    };
316"#);
317        assert!(val.float_field.is_nan());
318    }
319
320    #[test]
321    fn deserialize_unit() {
322        //language=JavaScript
323        let _val: () = deserialize_expr(r#"
324    value = {
325        test: "asfads"
326    };
327"#);
328    }
329}