1use rquickjs::{Array, Ctx, Object, String as JSString, Value, object::Property};
2use serde::{Serialize, ser};
3
4use crate::err::{Error, Result};
5
6pub struct Serializer<'js> {
25 pub context: Ctx<'js>,
26 pub value: Value<'js>,
27 pub key: Value<'js>,
28}
29
30impl<'js> Serializer<'js> {
31 pub fn from_context(context: Ctx<'js>) -> Result<Self> {
32 Ok(Self {
33 context: context.clone(),
34 value: Value::new_undefined(context.clone()),
35 key: Value::new_undefined(context),
36 })
37 }
38}
39
40impl ser::Serializer for &mut Serializer<'_> {
41 type Ok = ();
42 type Error = Error;
43
44 type SerializeSeq = Self;
45 type SerializeTuple = Self;
46 type SerializeTupleStruct = Self;
47 type SerializeTupleVariant = Self;
48 type SerializeMap = Self;
49 type SerializeStruct = Self;
50 type SerializeStructVariant = Self;
51
52 fn serialize_i8(self, v: i8) -> Result<()> {
53 self.serialize_i32(i32::from(v))
54 }
55
56 fn serialize_i16(self, v: i16) -> Result<()> {
57 self.serialize_i32(i32::from(v))
58 }
59
60 fn serialize_i32(self, v: i32) -> Result<()> {
61 self.value = Value::new_int(self.context.clone(), v);
62 Ok(())
63 }
64
65 fn serialize_i64(self, v: i64) -> Result<()> {
66 self.value = Value::new_number(self.context.clone(), v as _);
67 Ok(())
68 }
69
70 fn serialize_u8(self, v: u8) -> Result<()> {
71 self.serialize_i32(i32::from(v))
72 }
73
74 fn serialize_u16(self, v: u16) -> Result<()> {
75 self.serialize_i32(i32::from(v))
76 }
77
78 fn serialize_u32(self, v: u32) -> Result<()> {
79 self.serialize_f64(f64::from(v))
81 }
82
83 fn serialize_u64(self, v: u64) -> Result<()> {
84 self.value = Value::new_number(self.context.clone(), v as _);
85 Ok(())
86 }
87
88 fn serialize_f32(self, v: f32) -> Result<()> {
89 self.serialize_f64(f64::from(v))
91 }
92
93 fn serialize_f64(self, v: f64) -> Result<()> {
94 self.value = Value::new_float(self.context.clone(), v);
97 Ok(())
98 }
99
100 fn serialize_bool(self, b: bool) -> Result<()> {
101 self.value = Value::new_bool(self.context.clone(), b);
102 Ok(())
103 }
104
105 fn serialize_char(self, v: char) -> Result<()> {
106 self.serialize_str(&v.to_string())
107 }
108
109 fn serialize_str(self, v: &str) -> Result<()> {
110 let js_string = JSString::from_str(self.context.clone(), v).map_err(Error::new)?;
111 self.value = Value::from(js_string);
112 Ok(())
113 }
114
115 fn serialize_none(self) -> Result<()> {
116 self.serialize_unit()
117 }
118
119 fn serialize_unit(self) -> Result<()> {
120 self.value = Value::new_null(self.context.clone());
121 Ok(())
122 }
123
124 fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
125 self.serialize_unit()
126 }
127
128 fn serialize_some<T>(self, value: &T) -> Result<()>
129 where
130 T: ?Sized + Serialize,
131 {
132 value.serialize(self)
133 }
134
135 fn serialize_unit_variant(
136 self,
137 _name: &'static str,
138 _variant_index: u32,
139 variant: &'static str,
140 ) -> Result<()> {
141 self.serialize_str(variant)
142 }
143
144 fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
145 where
146 T: ?Sized + Serialize,
147 {
148 value.serialize(self)
149 }
150
151 fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
152 let arr = Array::new(self.context.clone()).map_err(Error::new)?;
153 self.value = arr.into_value();
154 Ok(self)
155 }
156
157 fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
158 self.serialize_seq(Some(len))
159 }
160
161 fn serialize_tuple_struct(
162 self,
163 _name: &'static str,
164 len: usize,
165 ) -> Result<Self::SerializeTupleStruct> {
166 self.serialize_seq(Some(len))
167 }
168
169 fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
170 let obj = Object::new(self.context.clone()).map_err(Error::new)?;
171 self.value = Value::from(obj);
172 Ok(self)
173 }
174
175 fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
176 self.serialize_map(Some(len))
177 }
178
179 fn serialize_struct_variant(
180 self,
181 _name: &'static str,
182 _variant_index: u32,
183 _variant: &'static str,
184 len: usize,
185 ) -> Result<Self::SerializeStructVariant> {
186 self.serialize_map(Some(len))
187 }
188
189 fn serialize_tuple_variant(
190 self,
191 _name: &'static str,
192 _variant_index: u32,
193 _variant: &'static str,
194 len: usize,
195 ) -> Result<Self::SerializeTupleVariant> {
196 self.serialize_map(Some(len))
197 }
198
199 fn serialize_newtype_variant<T>(
200 self,
201 _name: &'static str,
202 _variant_index: u32,
203 variant: &'static str,
204 value: &T,
205 ) -> Result<()>
206 where
207 T: ?Sized + Serialize,
208 {
209 let obj = Object::new(self.context.clone()).map_err(Error::new)?;
210 value.serialize(&mut *self)?;
211 obj.set(variant, self.value.clone()).map_err(Error::new)?;
212 self.value = Value::from(obj);
213
214 Ok(())
215 }
216
217 fn serialize_bytes(self, _: &[u8]) -> Result<()> {
218 Err(Error::new("Cannot serialize bytes"))
219 }
220}
221
222impl ser::SerializeSeq for &mut Serializer<'_> {
223 type Ok = ();
224 type Error = Error;
225
226 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
227 where
228 T: ?Sized + Serialize,
229 {
230 let mut element_serializer = Serializer::from_context(self.context.clone())?;
231 value.serialize(&mut element_serializer)?;
232
233 if let Some(v) = self.value.as_array() {
234 return v
235 .set(v.len(), element_serializer.value.clone())
236 .map_err(Error::new);
237 }
238 Err(Error::new("Expected to be an array"))
239 }
240
241 fn end(self) -> Result<()> {
242 Ok(())
243 }
244}
245
246impl ser::SerializeTuple for &mut Serializer<'_> {
247 type Ok = ();
248 type Error = Error;
249
250 fn serialize_element<T>(&mut self, value: &T) -> Result<()>
251 where
252 T: ?Sized + Serialize,
253 {
254 let mut element_serializer = Serializer::from_context(self.context.clone())?;
255 value.serialize(&mut element_serializer)?;
256
257 if let Some(v) = self.value.as_array() {
258 return v
259 .set(v.len(), element_serializer.value.clone())
260 .map_err(Error::new);
261 }
262
263 Err(Error::new("Expected to be an array"))
264 }
265
266 fn end(self) -> Result<()> {
267 Ok(())
268 }
269}
270
271impl ser::SerializeTupleStruct for &mut Serializer<'_> {
272 type Ok = ();
273 type Error = Error;
274
275 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
276 where
277 T: ?Sized + Serialize,
278 {
279 let mut field_serializer = Serializer::from_context(self.context.clone())?;
280 value.serialize(&mut field_serializer)?;
281 if let Some(v) = self.value.as_array() {
282 return v
283 .set(v.len(), field_serializer.value.clone())
284 .map_err(Error::new);
285 }
286
287 Err(Error::new("Expected to be an array"))
288 }
289
290 fn end(self) -> Result<()> {
291 Ok(())
292 }
293}
294
295impl ser::SerializeTupleVariant for &mut Serializer<'_> {
296 type Ok = ();
297 type Error = Error;
298
299 fn serialize_field<T>(&mut self, value: &T) -> Result<()>
300 where
301 T: ?Sized + Serialize,
302 {
303 let mut field_serializer = Serializer::from_context(self.context.clone())?;
304 value.serialize(&mut field_serializer)?;
305
306 if let Some(v) = self.value.as_array() {
307 return v
308 .set(v.len(), field_serializer.value.clone())
309 .map_err(Error::new);
310 }
311
312 Err(Error::new("Expected to be an array"))
313 }
314
315 fn end(self) -> Result<()> {
316 Ok(())
317 }
318}
319
320impl ser::SerializeMap for &mut Serializer<'_> {
321 type Ok = ();
322 type Error = Error;
323
324 fn serialize_key<T>(&mut self, key: &T) -> Result<()>
325 where
326 T: ?Sized + Serialize,
327 {
328 let mut key_serializer = Serializer::from_context(self.context.clone())?;
329 key.serialize(&mut key_serializer)?;
330 self.key = key_serializer.value;
331 Ok(())
332 }
333
334 fn serialize_value<T>(&mut self, value: &T) -> Result<()>
335 where
336 T: ?Sized + Serialize,
337 {
338 let mut map_serializer = Serializer::from_context(self.context.clone())?;
339 value.serialize(&mut map_serializer)?;
340 if let Some(o) = self.value.as_object() {
341 let prop = Property::from(map_serializer.value.clone())
342 .writable()
343 .configurable()
344 .enumerable();
345 o.prop::<_, _, _>(self.key.clone(), prop)
346 .map_err(Error::new)
347 } else {
348 Err(Error::new("Expected to be an object"))
349 }
350 }
351
352 fn end(self) -> Result<()> {
353 Ok(())
354 }
355}
356
357impl ser::SerializeStruct for &mut Serializer<'_> {
358 type Ok = ();
359 type Error = Error;
360
361 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
362 where
363 T: ?Sized + Serialize,
364 {
365 let mut field_serializer = Serializer::from_context(self.context.clone())?;
366 value.serialize(&mut field_serializer)?;
367
368 if let Some(o) = self.value.as_object() {
369 return o
370 .set(key, field_serializer.value.clone())
371 .map_err(Error::new);
372 }
373
374 Err(Error::new("Expected to be an object"))
375 }
376
377 fn end(self) -> Result<()> {
378 Ok(())
379 }
380}
381
382impl ser::SerializeStructVariant for &mut Serializer<'_> {
383 type Ok = ();
384 type Error = Error;
385
386 fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
387 where
388 T: ?Sized + Serialize,
389 {
390 let mut field_serializer = Serializer::from_context(self.context.clone())?;
391 value.serialize(&mut field_serializer)?;
392
393 if let Some(o) = self.value.as_object() {
394 return o
395 .set(key, field_serializer.value.clone())
396 .map_err(Error::new);
397 }
398
399 Err(Error::new("Expected to be an object"))
400 }
401
402 fn end(self) -> Result<()> {
403 Ok(())
404 }
405}
406
407#[cfg(test)]
408mod tests {
409 use std::collections::BTreeMap;
410
411 use serde::{Serialize, Serializer};
412
413 use super::Serializer as ValueSerializer;
414 use crate::err::Result;
415 use crate::test::Runtime;
416 use crate::{MAX_SAFE_INTEGER, MIN_SAFE_INTEGER};
417 use quickcheck::quickcheck;
418
419 fn with_serializer<F: FnMut(&mut ValueSerializer) -> Result<bool>>(
420 rt: &Runtime,
421 mut w: F,
422 ) -> Result<bool> {
423 rt.context().with(|c| {
424 let mut serializer = ValueSerializer::from_context(c.clone()).unwrap();
425 w(&mut serializer)
426 })
427 }
428
429 quickcheck! {
430 fn test_i16(v: i16) -> Result<bool> {
431 let rt = Runtime::default();
432 with_serializer(&rt, |serializer| {
433 serializer.serialize_i16(v)?;
434 Ok(serializer.value.is_int())
435 })
436 }
437
438 fn test_i32(v: i32) -> Result<bool> {
439 let rt = Runtime::default();
440 with_serializer(&rt, |serializer| {
441 serializer.serialize_i32(v)?;
442 Ok(serializer.value.is_int())
443 })
444 }
445
446 fn test_i64(v: i64) -> Result<bool> {
447 let rt = Runtime::default();
448 with_serializer(&rt, |serializer| {
449 if (MIN_SAFE_INTEGER..=MAX_SAFE_INTEGER).contains(&v) {
450 serializer.serialize_i64(v)?;
451 Ok(serializer.value.is_number())
452 } else {
453 serializer.serialize_f64(v as f64)?;
454 Ok(serializer.value.is_number())
455 }
456 })
457 }
458
459 fn test_u64(v: u64) -> Result<bool> {
460 let rt = Runtime::default();
461 with_serializer(&rt, |serializer| {
462 if v <= MAX_SAFE_INTEGER as u64 {
463 serializer.serialize_u64(v)?;
464 Ok(serializer.value.is_number())
465 } else {
466 serializer.serialize_f64(v as f64)?;
467 Ok(serializer.value.is_number())
468 }
469 })
470 }
471
472 fn test_u16(v: u16) -> Result<bool> {
473 let rt = Runtime::default();
474
475 with_serializer(&rt, |serializer| {
476 serializer.serialize_u16(v)?;
477 Ok(serializer.value.is_int())
478 })
479 }
480
481 fn test_u32(v: u32) -> Result<bool> {
482 let rt = Runtime::default();
483 with_serializer(&rt, |serializer| {
484 serializer.serialize_u32(v)?;
485 if v > i32::MAX as u32 {
488 Ok(serializer.value.is_float())
489 } else {
490 Ok(serializer.value.is_int())
491 }
492 })
493
494 }
495
496 fn test_f32(v: f32) -> Result<bool> {
497 let rt = Runtime::default();
498 with_serializer(&rt, |serializer| {
499 serializer.serialize_f32(v)?;
500
501 if v == 0.0_f32 {
502 if v.is_sign_positive() {
503 return Ok(serializer.value.is_int());
504 }
505
506
507 if v.is_sign_negative() {
508 return Ok(serializer.value.is_float());
509 }
510 }
511
512 let zero_fractional_part = v.fract() == 0.0;
515 let range = (i32::MIN as f32)..=(i32::MAX as f32);
516
517 if zero_fractional_part && range.contains(&v) {
518 Ok(serializer.value.is_int())
519 } else {
520 Ok(serializer.value.is_float())
521 }
522 })
523 }
524
525 fn test_f64(v: f64) -> Result<bool> {
526 let rt = Runtime::default();
527 with_serializer(&rt, |serializer| {
528 serializer.serialize_f64(v)?;
529
530 if v == 0.0_f64 {
531 if v.is_sign_positive() {
532 return Ok(serializer.value.is_int());
533 }
534
535
536 if v.is_sign_negative() {
537 return Ok(serializer.value.is_float());
538 }
539 }
540
541 let zero_fractional_part = v.fract() == 0.0;
544 let range = (i32::MIN as f64)..=(i32::MAX as f64);
545
546 if zero_fractional_part && range.contains(&v) {
547 Ok(serializer.value.is_int())
548 } else {
549 Ok(serializer.value.is_float())
550 }
551 })
552 }
553
554 fn test_bool(v: bool) -> Result<bool> {
555 let rt = Runtime::default();
556 with_serializer(&rt, |serializer| {
557 serializer.serialize_bool(v)?;
558 Ok(serializer.value.is_bool())
559 })
560 }
561
562 fn test_str(v: String) -> Result<bool> {
563 let rt = Runtime::default();
564 with_serializer(&rt, |serializer| {
565 serializer.serialize_str(v.as_str())?;
566
567 Ok(serializer.value.is_string())
568 })
569 }
570 }
571
572 #[test]
573 fn test_null() -> Result<()> {
574 let rt = Runtime::default();
575
576 rt.context().with(|cx| {
577 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
578 serializer.serialize_unit().unwrap();
579
580 assert!(serializer.value.is_null());
581 });
582 Ok(())
583 }
584
585 #[test]
586 fn test_nan() -> Result<()> {
587 let rt = Runtime::default();
588
589 rt.context().with(|cx| {
590 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
591 serializer.serialize_f64(f64::NAN).unwrap();
592 assert!(serializer.value.is_number());
593 });
594 Ok(())
595 }
596
597 #[test]
598 fn test_infinity() -> Result<()> {
599 let rt = Runtime::default();
600 rt.context().with(|cx| {
601 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
602 serializer.serialize_f64(f64::INFINITY).unwrap();
603 assert!(serializer.value.is_number());
604 });
605 Ok(())
606 }
607
608 #[test]
609 fn test_negative_infinity() -> Result<()> {
610 let rt = Runtime::default();
611 rt.context().with(|cx| {
612 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
613 serializer.serialize_f64(f64::NEG_INFINITY).unwrap();
614 assert!(serializer.value.is_number());
615 });
616 Ok(())
617 }
618
619 #[test]
620 fn test_map() {
621 let rt = Runtime::default();
622
623 rt.context().with(|cx| {
624 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
625
626 let mut map = BTreeMap::new();
627 map.insert("foo", "bar");
628 map.insert("toto", "titi");
629
630 map.serialize(&mut serializer).unwrap();
631
632 assert!(serializer.value.is_object())
633 });
634 }
635
636 #[test]
637 fn test_struct_into_map() {
638 let rt = Runtime::default();
639
640 rt.context().with(|cx| {
641 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
642
643 #[derive(serde::Serialize)]
644 struct MyObject {
645 foo: String,
646 bar: u32,
647 }
648
649 let my_object = MyObject {
650 foo: "hello".to_string(),
651 bar: 1337,
652 };
653 my_object.serialize(&mut serializer).unwrap();
654
655 assert!(serializer.value.is_object());
656 });
657 }
658
659 #[test]
660 fn test_sequence() {
661 let rt = Runtime::default();
662
663 rt.context().with(|cx| {
664 let mut serializer = ValueSerializer::from_context(cx.clone()).unwrap();
665
666 let sequence = vec!["hello", "world"];
667
668 sequence.serialize(&mut serializer).unwrap();
669
670 assert!(serializer.value.is_array());
671 });
672 }
673}