kg_js/
ser.rs

1use super::*;
2use serde::ser::*;
3
4impl<T: Serialize> WriteJs for T {
5    fn write_js(&self, ctx: &DukContext) -> Result<(), JsError> {
6        self.serialize(JsEngineSerializer { ctx, index: 0 })
7    }
8}
9
10impl serde::ser::Error for JsError {
11    fn custom<T>(msg: T) -> Self where T: std::fmt::Display {
12        Self::from(msg.to_string())
13    }
14}
15
16impl serde::de::Error for JsError {
17    fn custom<T>(msg: T) -> Self where T: std::fmt::Display {
18        Self::from(msg.to_string())
19    }
20}
21
22
23pub struct JsEngineSerializer<'a> {
24    ctx: &'a DukContext,
25    index: u32,
26}
27
28impl <'a> JsEngineSerializer<'a> {
29    pub fn new(ctx: &'a mut DukContext) -> Self {
30        Self { ctx, index: 0 }
31    }
32}
33
34impl<'a> Serializer for JsEngineSerializer<'a> {
35    type Ok = ();
36    type Error = JsError;
37    type SerializeSeq = Self;
38    type SerializeTuple = Self;
39    type SerializeTupleStruct = Self;
40    type SerializeTupleVariant = Self;
41    type SerializeMap = Self;
42    type SerializeStruct = Self;
43    type SerializeStructVariant = Self;
44
45    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
46        self.ctx.push_boolean(v);
47        Ok(())
48    }
49
50    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
51        self.ctx.push_i32(v as i32);
52        Ok(())
53    }
54
55    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
56        self.ctx.push_i32(v as i32);
57        Ok(())
58    }
59
60    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
61        self.ctx.push_i32(v);
62        Ok(())
63    }
64
65    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
66        self.ctx.push_number(v as f64);
67        Ok(())
68    }
69
70    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
71        self.ctx.push_u32(v as u32);
72        Ok(())
73    }
74
75    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
76        self.ctx.push_u32(v as u32);
77        Ok(())
78    }
79
80    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
81        self.ctx.push_u32(v as u32);
82        Ok(())
83    }
84
85    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
86        self.ctx.push_number(v as f64);
87        Ok(())
88    }
89
90    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
91        self.ctx.push_number(v as f64);
92        Ok(())
93    }
94
95    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
96        self.ctx.push_number(v);
97        Ok(())
98    }
99
100    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
101        let mut tmp = [0; 4];
102        self.ctx.push_string(v.encode_utf8(&mut tmp));
103        Ok(())
104    }
105
106    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
107        self.ctx.push_string(v);
108        Ok(())
109    }
110
111    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
112        self.ctx.push_ext_buffer(v);
113        Ok(())
114    }
115
116    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
117        self.ctx.push_null();
118        Ok(())
119    }
120
121    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> where T: Serialize {
122        value.serialize(self)
123    }
124
125    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
126        self.ctx.push_null();
127        Ok(())
128    }
129
130    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
131        self.ctx.push_null();
132        Ok(())
133    }
134
135    fn serialize_unit_variant(self, _name: &'static str, _variant_index: u32, variant: &'static str) -> Result<Self::Ok, Self::Error> {
136        self.ctx.push_string(variant);
137        Ok(())
138    }
139
140    fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> Result<Self::Ok, Self::Error> where T: Serialize {
141        value.serialize(self)
142    }
143
144    fn serialize_newtype_variant<T: ?Sized>(self, _name: &'static str, _variant_index: u32, variant: &'static str, value: &T) -> Result<Self::Ok, Self::Error> where T: Serialize {
145        self.ctx.push_object();
146        value.serialize(JsEngineSerializer { ctx: self.ctx, index: 0 })?;
147        self.ctx.put_prop_string(-2, variant);
148        Ok(())
149    }
150
151    fn serialize_seq(mut self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
152        self.ctx.push_array();
153        self.index = 0;
154        Ok(self)
155    }
156
157    fn serialize_tuple(mut self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
158        self.ctx.push_array();
159        self.index = 0;
160        Ok(self)
161    }
162
163    fn serialize_tuple_struct(mut self, _name: &'static str, _len: usize) -> Result<Self::SerializeTupleStruct, Self::Error> {
164        self.ctx.push_array();
165        self.index = 0;
166        Ok(self)
167    }
168
169    fn serialize_tuple_variant(mut self, _name: &'static str, _variant_index: u32, variant: &'static str, _len: usize) -> Result<Self::SerializeTupleVariant, Self::Error> {
170        self.ctx.push_object();
171        self.ctx.push_string(variant);
172        self.ctx.push_array();
173        self.index = 0;
174        Ok(self)
175    }
176
177    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
178        self.ctx.push_object();
179        Ok(self)
180    }
181
182    fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct, Self::Error> {
183        self.ctx.push_object();
184        Ok(self)
185    }
186
187    fn serialize_struct_variant(self, _name: &'static str, _variant_index: u32, variant: &'static str, _len: usize) -> Result<Self::SerializeStructVariant, Self::Error> {
188        self.ctx.push_object();
189        self.ctx.push_string(variant);
190        self.ctx.push_object();
191        Ok(self)
192    }
193}
194
195impl<'a> SerializeSeq for JsEngineSerializer<'a> {
196    type Ok = ();
197    type Error = JsError;
198
199    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
200        value.serialize(JsEngineSerializer { ctx: self.ctx, index: 0 })?;
201        self.ctx.put_prop_index(-2, self.index);
202        self.index += 1;
203        Ok(())
204    }
205
206    fn end(self) -> Result<Self::Ok, Self::Error> {
207        Ok(())
208    }
209}
210
211impl<'a> SerializeTuple for JsEngineSerializer<'a> {
212    type Ok = ();
213    type Error = JsError;
214
215    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
216        SerializeSeq::serialize_element(self, value)
217    }
218
219    fn end(self) -> Result<Self::Ok, Self::Error> {
220        Ok(())
221    }
222}
223
224impl<'a> SerializeTupleVariant for JsEngineSerializer<'a> {
225    type Ok = ();
226    type Error = JsError;
227
228    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
229        SerializeSeq::serialize_element(self, value)
230    }
231
232    fn end(self) -> Result<Self::Ok, Self::Error> {
233        self.ctx.put_prop(-3);
234        Ok(())
235    }
236}
237
238impl<'a> SerializeTupleStruct for JsEngineSerializer<'a> {
239    type Ok = ();
240    type Error = JsError;
241
242    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
243        SerializeSeq::serialize_element(self, value)
244    }
245
246    fn end(self) -> Result<Self::Ok, Self::Error> {
247        Ok(())
248    }
249}
250
251impl<'a> SerializeStruct for JsEngineSerializer<'a> {
252    type Ok = ();
253    type Error = JsError;
254
255    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize {
256        value.serialize(JsEngineSerializer { ctx: self.ctx, index: 0 })?;
257        self.ctx.put_prop_string(-2, key);
258        Ok(())
259    }
260
261    fn end(self) -> Result<Self::Ok, Self::Error> {
262        Ok(())
263    }
264}
265
266impl<'a> SerializeStructVariant for JsEngineSerializer<'a> {
267    type Ok = ();
268    type Error = JsError;
269
270    fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> where T: Serialize {
271        SerializeStruct::serialize_field(self, key, value)
272    }
273
274    fn end(self) -> Result<Self::Ok, Self::Error> {
275        self.ctx.put_prop(-3);
276        Ok(())
277    }
278}
279
280impl<'a> SerializeMap for JsEngineSerializer<'a> {
281    type Ok = ();
282    type Error = JsError;
283
284    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error> where T: Serialize {
285        key.serialize(JsEngineSerializer { ctx: self.ctx, index: 0 })
286    }
287
288    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error> where T: Serialize {
289        value.serialize(JsEngineSerializer { ctx: self.ctx, index: 0 })?;
290        self.ctx.put_prop(-3);
291        Ok(())
292    }
293
294    fn end(self) -> Result<Self::Ok, Self::Error> {
295        Ok(())
296    }
297}
298
299
300#[cfg(test)]
301mod tests {
302    use super::*;
303    use smart_default::SmartDefault;
304    use serde::{Serialize, Deserialize};
305
306    fn serialize<T: Serialize>(value: &T) -> String {
307        let e = JsEngine::new().unwrap();
308        e.write(value).unwrap_or_else(|err| {
309            panic!("{}", err);
310        });
311        e.put_global_string("value");
312        e.eval( r#"var enc = Duktape.enc('jc', value, null, 2);"#).unwrap();
313        e.get_global_string("enc");
314        e.get_string(-1).to_string()
315    }
316
317    fn test_serialize<T: Serialize>(value: &T) {
318        let s = serialize(value);
319        assert_eq!(serde_json::to_string_pretty(value).unwrap(), s);
320    }
321
322    #[derive(SmartDefault, Serialize, Deserialize)]
323    struct TestStruct {
324        #[default = "string value"]
325        string_field: String,
326        #[default = 'A']
327        char_field: char,
328        #[default = 1]
329        i8_field: i8,
330    }
331
332    #[derive(SmartDefault, Serialize, Deserialize)]
333    struct TestStruct2 {
334        struct_field: TestStruct,
335        #[default(_code = "('A', 'B', 'C')")]
336        unit_char_field: (char, char, char),
337        #[default(_code = "vec![1, 2 ,3]")]
338        array_i8_field: Vec<i8>,
339    }
340
341    #[test]
342    fn write_string() {
343        let p = String::from("string value");
344        test_serialize(&p);
345    }
346
347    #[test]
348    fn write_bytes() {
349        struct Bytes<'a>(&'a [u8]);
350
351        impl<'a> Serialize for Bytes<'a> {
352            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
353                serializer.serialize_bytes(self.0)
354            }
355        }
356
357        let p = Bytes("byte data".as_bytes());
358        let ser = serialize(&p);
359        assert_eq!(ser, r#"{"_buf":"627974652064617461"}"#);
360        assert_eq!(p.0, "byte data".as_bytes());
361    }
362
363    #[test]
364    fn write_struct() {
365        let p = TestStruct2::default();
366        test_serialize(&p);
367    }
368
369    #[test]
370    fn write_option_none() {
371        let p: Option<TestStruct2> = None;
372        test_serialize(&p);
373    }
374
375    #[test]
376    fn write_option_some() {
377        let p: Option<TestStruct2> = Some(TestStruct2::default());
378        test_serialize(&p);
379    }
380
381    #[test]
382    fn write_enum_unit_variant() {
383        #[derive(SmartDefault, Serialize, Deserialize)]
384        enum TestEnum {
385            #[default]
386            Empty,
387        }
388        let p = TestEnum::default();
389        test_serialize(&p);
390    }
391
392    #[test]
393    fn write_enum_tuple_variant() {
394        #[derive(SmartDefault, Serialize, Deserialize)]
395        enum TestEnum {
396            #[default]
397            Tuple(
398                #[default = "string val"]
399                String,
400                TestStruct,
401                #[default(_code = "(1, 2, 12.5)")]
402                (i8, u32, f64),
403            ),
404        }
405        let p = TestEnum::default();
406        test_serialize(&p);
407    }
408
409    #[test]
410    fn write_enum_struct_variant() {
411        #[derive(SmartDefault, Serialize, Deserialize)]
412        enum TestEnum {
413            #[default]
414            Struct {
415                #[default = "string val"]
416                str_field: String,
417                struct_field: TestStruct,
418                #[default = 12.5]
419                float_field: f64,
420            },
421        }
422        let p = TestEnum::default();
423        test_serialize(&p);
424    }
425
426    #[test]
427    fn write_struct_variant() {
428        #[derive(SmartDefault, Serialize, Deserialize)]
429        struct TestStructVariant(
430            #[default = "string val"]
431            String,
432            TestStruct,
433            #[default = 12.5]
434            f64
435        );
436
437        let p = TestStructVariant::default();
438        test_serialize(&p);
439    }
440
441    #[test]
442    fn write_unit_struct() {
443        #[derive(Serialize, Deserialize)]
444        struct TestUnitStruct;
445
446        let p = TestUnitStruct;
447        test_serialize(&p);
448    }
449
450    #[test]
451    fn write_newtype_struct() {
452        #[derive(Serialize, Deserialize)]
453        struct TestNewtypeStruct(f64);
454
455        let p = TestNewtypeStruct(15.9);
456        test_serialize(&p);
457    }
458
459    #[test]
460    fn write_newtype_variant() {
461        #[derive(Serialize, Deserialize)]
462        enum TestEnum {
463            Newtype(f64)
464        }
465
466        let p = TestEnum::Newtype(15.9);
467        test_serialize(&p);
468    }
469
470    #[test]
471    fn write_map() {
472        use std::collections::BTreeMap;
473        let mut map: BTreeMap<&str, TestStruct> = BTreeMap::new();
474        map.insert("key1", TestStruct::default());
475        map.insert("key2", TestStruct::default());
476        map.insert("key3", TestStruct::default());
477
478        test_serialize(&map);
479    }
480}