neon_serde2/
ser.rs

1//!
2//! Serialize a Rust data structure into a `JsValue`
3//!
4
5use errors::Error;
6use errors::ErrorKind;
7use errors::Result as LibResult;
8use neon::prelude::*;
9use serde::ser::{self, Serialize};
10use std::marker::PhantomData;
11use num;
12
13fn as_num<T: num::cast::NumCast, OutT: num::cast::NumCast>(n: T) -> LibResult<OutT> {
14    match num::cast::<T, OutT>(n) {
15        Some(n2) => Ok(n2),
16        None => bail!(ErrorKind::CastError)
17    }
18}
19
20/// Converts a value of type `V` to a `JsValue`
21///
22/// # Errors
23///
24/// * `NumberCastError` trying to serialize a `u64` can fail if it overflows in a cast to `f64`
25/// * `StringTooLong` if the string exceeds v8's max string size
26///
27#[inline]
28pub fn to_value<'j, C, V>(cx: &mut C, value: &V) -> LibResult<Handle<'j, JsValue>>
29where
30    C: Context<'j>,
31    V: Serialize + ?Sized,
32{
33    let serializer = Serializer {
34        cx,
35        ph: PhantomData,
36    };
37    let serialized_value = value.serialize(serializer)?;
38    Ok(serialized_value)
39}
40
41#[doc(hidden)]
42pub struct Serializer<'a, 'j, C: 'a>
43where
44    C: Context<'j>,
45{
46    cx: &'a mut C,
47    ph: PhantomData<&'j ()>,
48}
49
50#[doc(hidden)]
51pub struct ArraySerializer<'a, 'j, C: 'a>
52where
53    C: Context<'j>,
54{
55    cx: &'a mut C,
56    array: Handle<'j, JsArray>,
57}
58
59#[doc(hidden)]
60pub struct TupleVariantSerializer<'a, 'j, C: 'a>
61where
62    C: Context<'j>,
63{
64    outter_object: Handle<'j, JsObject>,
65    inner: ArraySerializer<'a, 'j, C>,
66}
67
68#[doc(hidden)]
69pub struct MapSerializer<'a, 'j, C: 'a>
70where
71    C: Context<'j>,
72{
73    cx: &'a mut C,
74    object: Handle<'j, JsObject>,
75    key_holder: Handle<'j, JsObject>,
76}
77
78#[doc(hidden)]
79pub struct StructSerializer<'a, 'j, C: 'a>
80where
81    C: Context<'j>,
82{
83    cx: &'a mut C,
84    object: Handle<'j, JsObject>,
85}
86
87#[doc(hidden)]
88pub struct StructVariantSerializer<'a, 'j, C: 'a>
89where
90    C: Context<'j>,
91{
92    outer_object: Handle<'j, JsObject>,
93    inner: StructSerializer<'a, 'j, C>,
94}
95
96#[doc(hidden)]
97impl<'a, 'j, C> ser::Serializer for Serializer<'a, 'j, C>
98where
99    C: Context<'j>,
100{
101    type Ok = Handle<'j, JsValue>;
102    type Error = Error;
103
104    type SerializeSeq = ArraySerializer<'a, 'j, C>;
105    type SerializeTuple = ArraySerializer<'a, 'j, C>;
106    type SerializeTupleStruct = ArraySerializer<'a, 'j, C>;
107    type SerializeTupleVariant = TupleVariantSerializer<'a, 'j, C>;
108    type SerializeMap = MapSerializer<'a, 'j, C>;
109    type SerializeStruct = StructSerializer<'a, 'j, C>;
110    type SerializeStructVariant = StructVariantSerializer<'a, 'j, C>;
111
112    #[inline]
113    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
114        Ok(JsBoolean::new(self.cx, v).upcast())
115    }
116
117    #[inline]
118    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
119        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
120    }
121
122    #[inline]
123    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
124        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
125    }
126
127    #[inline]
128    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
129        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
130    }
131
132    #[inline]
133    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
134        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
135    }
136
137    #[inline]
138    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
139        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
140    }
141
142
143    #[inline]
144    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
145        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
146    }
147
148    #[inline]
149    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
150        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
151    }
152
153    #[inline]
154    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
155        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
156    }
157
158    #[inline]
159    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
160        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
161    }
162
163    #[inline]
164    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
165        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
166    }
167
168    #[inline]
169    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
170        Ok(JsNumber::new(self.cx, as_num::<_, f64>(v)?).upcast())
171    }
172
173    #[inline]
174    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
175        Ok(JsNumber::new(self.cx, v).upcast())
176    }
177
178    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
179        let mut b = [0; 4];
180        let result = v.encode_utf8(&mut b);
181        let js_str = JsString::try_new(self.cx, result)
182            .map_err(|_| ErrorKind::StringTooLongForChar(4))?;
183        Ok(js_str.upcast())
184    }
185
186    #[inline]
187    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
188        let len = v.len();
189        let js_str = JsString::try_new(self.cx, v).map_err(|_| ErrorKind::StringTooLong(len))?;
190        Ok(js_str.upcast())
191    }
192
193    #[inline]
194    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
195        let mut buff = JsBuffer::new(self.cx, as_num::<_, u32>(v.len())?)?;
196        self.cx.borrow_mut(&mut buff, |buff| buff.as_mut_slice().clone_from_slice(v));
197        Ok(buff.upcast())
198    }
199
200    #[inline]
201    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
202        Ok(JsNull::new(self.cx).upcast())
203    }
204
205    #[inline]
206    fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
207    where
208        T: Serialize,
209    {
210        value.serialize(self)
211    }
212
213    #[inline]
214    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
215        Ok(JsNull::new(self.cx).upcast())
216    }
217
218    #[inline]
219    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
220        Ok(JsNull::new(self.cx).upcast())
221    }
222
223    #[inline]
224    fn serialize_unit_variant(
225        self,
226        _name: &'static str,
227        _variant_index: u32,
228        variant: &'static str,
229    ) -> Result<Self::Ok, Self::Error> {
230        self.serialize_str(variant)
231    }
232
233    #[inline]
234    fn serialize_newtype_struct<T: ?Sized>(
235        self,
236        _name: &'static str,
237        value: &T,
238    ) -> Result<Self::Ok, Self::Error>
239    where
240        T: Serialize,
241    {
242        value.serialize(self)
243    }
244
245    #[inline]
246    fn serialize_newtype_variant<T: ?Sized>(
247        self,
248        _name: &'static str,
249        _variant_index: u32,
250        variant: &'static str,
251        value: &T,
252    ) -> Result<Self::Ok, Self::Error>
253    where
254        T: Serialize,
255    {
256        let obj = JsObject::new(&mut *self.cx);
257        let value_js = to_value(self.cx, value)?;
258        obj.set(self.cx, variant, value_js)?;
259
260        Ok(obj.upcast())
261    }
262
263    #[inline]
264    fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
265        Ok(ArraySerializer::new(self.cx))
266    }
267
268    #[inline]
269    fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
270        Ok(ArraySerializer::new(self.cx))
271    }
272
273    #[inline]
274    fn serialize_tuple_struct(
275        self,
276        _name: &'static str,
277        _len: usize,
278    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
279        Ok(ArraySerializer::new(self.cx))
280    }
281
282    #[inline]
283    fn serialize_tuple_variant(
284        self,
285        _name: &'static str,
286        _variant_index: u32,
287        variant: &'static str,
288        _len: usize,
289    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
290        TupleVariantSerializer::new(self.cx, variant)
291    }
292
293    #[inline]
294    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
295        Ok(MapSerializer::new(self.cx))
296    }
297
298    #[inline]
299    fn serialize_struct(
300        self,
301        _name: &'static str,
302        _len: usize,
303    ) -> Result<Self::SerializeStruct, Self::Error> {
304        Ok(StructSerializer::new(self.cx))
305    }
306
307    #[inline]
308    fn serialize_struct_variant(
309        self,
310        _name: &'static str,
311        _variant_index: u32,
312        variant: &'static str,
313        _len: usize,
314    ) -> Result<Self::SerializeStructVariant, Self::Error> {
315        StructVariantSerializer::new(self.cx, variant)
316    }
317}
318
319#[doc(hidden)]
320impl<'a, 'j, C> ArraySerializer<'a, 'j, C>
321where
322    C: Context<'j>,
323{
324    #[inline]
325    fn new(cx: &'a mut C) -> Self {
326        let array = JsArray::new(cx, 0);
327        ArraySerializer { cx, array }
328    }
329}
330
331#[doc(hidden)]
332impl<'a, 'j, C> ser::SerializeSeq for ArraySerializer<'a, 'j, C>
333where
334    C: Context<'j>,
335{
336    type Ok = Handle<'j, JsValue>;
337    type Error = Error;
338
339    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
340    where
341        T: Serialize,
342    {
343        let value = to_value(self.cx, value)?;
344
345        let arr: Handle<'j, JsArray> = self.array;
346        let len = arr.len(self.cx);
347        arr.set(self.cx, len, value)?;
348        Ok(())
349    }
350
351    #[inline]
352    fn end(self) -> Result<Self::Ok, Self::Error> {
353        Ok(self.array.upcast())
354    }
355}
356
357impl<'a, 'j, C> ser::SerializeTuple for ArraySerializer<'a, 'j, C>
358where
359    C: Context<'j>,
360{
361    type Ok = Handle<'j, JsValue>;
362    type Error = Error;
363
364    #[inline]
365    fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
366    where
367        T: Serialize,
368    {
369        ser::SerializeSeq::serialize_element(self, value)
370    }
371
372    #[inline]
373    fn end(self) -> Result<Self::Ok, Self::Error> {
374        ser::SerializeSeq::end(self)
375    }
376}
377
378#[doc(hidden)]
379impl<'a, 'j, C> ser::SerializeTupleStruct for ArraySerializer<'a, 'j, C>
380where
381    C: Context<'j>,
382{
383    type Ok = Handle<'j, JsValue>;
384    type Error = Error;
385
386    #[inline]
387    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
388    where
389        T: Serialize,
390    {
391        ser::SerializeSeq::serialize_element(self, value)
392    }
393
394    #[inline]
395    fn end(self) -> Result<Self::Ok, Self::Error> {
396        ser::SerializeSeq::end(self)
397    }
398}
399
400#[doc(hidden)]
401impl<'a, 'j, C> TupleVariantSerializer<'a, 'j, C>
402where
403    C: Context<'j>,
404{
405    fn new(cx: &'a mut C, key: &'static str) -> LibResult<Self> {
406        let inner_array = JsArray::new(cx, 0);
407        let outter_object = JsObject::new(cx);
408        outter_object.set(cx, key, inner_array)?;
409        Ok(TupleVariantSerializer {
410            outter_object,
411            inner: ArraySerializer {
412                cx,
413                array: inner_array,
414            },
415        })
416    }
417}
418
419#[doc(hidden)]
420impl<'a, 'j, C> ser::SerializeTupleVariant for TupleVariantSerializer<'a, 'j, C>
421where
422    C: Context<'j>,
423{
424    type Ok = Handle<'j, JsValue>;
425    type Error = Error;
426
427    #[inline]
428    fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
429    where
430        T: Serialize,
431    {
432        use serde::ser::SerializeSeq;
433        self.inner.serialize_element(value)
434    }
435
436    #[inline]
437    fn end(self) -> Result<Self::Ok, Self::Error> {
438        Ok(self.outter_object.upcast())
439    }
440}
441
442#[doc(hidden)]
443impl<'a, 'j, C> MapSerializer<'a, 'j, C>
444where
445    C: Context<'j>,
446{
447    fn new(cx: &'a mut C) -> Self {
448        let object = JsObject::new(cx);
449        let key_holder = JsObject::new(cx);
450        MapSerializer {
451            cx,
452            object,
453            key_holder,
454        }
455    }
456}
457
458#[doc(hidden)]
459impl<'a, 'j, C> ser::SerializeMap for MapSerializer<'a, 'j, C>
460where
461    C: Context<'j>,
462{
463    type Ok = Handle<'j, JsValue>;
464    type Error = Error;
465
466    fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
467    where
468        T: Serialize,
469    {
470        let key = to_value(self.cx, key)?;
471        self.key_holder.set(self.cx, "key", key)?;
472        Ok(())
473    }
474
475    fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
476    where
477        T: Serialize,
478    {
479        let key: Handle<'j, JsValue> = self.key_holder.get(&mut *self.cx, "key")?;
480        let value_obj = to_value(self.cx, value)?;
481        self.object.set(self.cx, key, value_obj)?;
482        Ok(())
483    }
484
485    #[inline]
486    fn end(self) -> Result<Self::Ok, Self::Error> {
487        Ok(self.object.upcast())
488    }
489}
490
491#[doc(hidden)]
492impl<'a, 'j, C> StructSerializer<'a, 'j, C>
493where
494    C: Context<'j>,
495{
496    #[inline]
497    fn new(cx: &'a mut C) -> Self {
498        let object = JsObject::new(cx);
499        StructSerializer { cx, object }
500    }
501}
502
503#[doc(hidden)]
504impl<'a, 'j, C> ser::SerializeStruct for StructSerializer<'a, 'j, C>
505where
506    C: Context<'j>,
507{
508    type Ok = Handle<'j, JsValue>;
509    type Error = Error;
510
511    #[inline]
512    fn serialize_field<T: ?Sized>(
513        &mut self,
514        key: &'static str,
515        value: &T,
516    ) -> Result<(), Self::Error>
517    where
518        T: Serialize,
519    {
520        let value = to_value(self.cx, value)?;
521        self.object.set(self.cx, key, value)?;
522        Ok(())
523    }
524
525    #[inline]
526    fn end(self) -> Result<Self::Ok, Self::Error> {
527        Ok(self.object.upcast())
528    }
529}
530
531#[doc(hidden)]
532impl<'a, 'j, C> StructVariantSerializer<'a, 'j, C>
533where
534    C: Context<'j>,
535{
536    fn new(cx: &'a mut C, key: &'static str) -> LibResult<Self> {
537        let inner_object = JsObject::new(cx);
538        let outter_object = JsObject::new(cx);
539        outter_object.set(cx, key, inner_object)?;
540        Ok(StructVariantSerializer {
541            outer_object: outter_object,
542            inner: StructSerializer {
543                cx,
544                object: inner_object,
545            },
546        })
547    }
548}
549
550#[doc(hidden)]
551impl<'a, 'j, C> ser::SerializeStructVariant for StructVariantSerializer<'a, 'j, C>
552where
553    C: Context<'j>,
554{
555    type Ok = Handle<'j, JsValue>;
556    type Error = Error;
557
558    #[inline]
559    fn serialize_field<T: ?Sized>(
560        &mut self,
561        key: &'static str,
562        value: &T,
563    ) -> Result<(), Self::Error>
564    where
565        T: Serialize,
566    {
567        use serde::ser::SerializeStruct;
568        self.inner.serialize_field(key, value)
569    }
570
571    #[inline]
572    fn end(self) -> Result<Self::Ok, Self::Error> {
573        Ok(self.outer_object.upcast())
574    }
575}