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}