rustler/serde/
ser.rs

1use std::io::Write;
2
3use crate::serde::{atoms, error::Error, util};
4use crate::wrapper::list::make_list;
5use crate::{types::tuple, Encoder, Env, OwnedBinary, Term};
6use serde::ser::{self, Serialize};
7
8#[inline]
9/// Converts a native Rust type into a native BEAM term. See conversion table
10/// for details about serialization behavior.
11pub fn to_term<T>(env: Env, value: T) -> Result<Term, Error>
12where
13    T: Serialize,
14{
15    value.serialize(Serializer::from(env))
16}
17
18#[derive(Clone, Copy)]
19pub struct Serializer<'a> {
20    env: Env<'a>,
21    non_finite_float_as_atom: bool,
22}
23
24impl<'a> From<Env<'a>> for Serializer<'a> {
25    fn from(env: Env<'a>) -> Serializer<'a> {
26        Serializer {
27            env,
28            non_finite_float_as_atom: false,
29        }
30    }
31}
32
33impl<'a> ser::Serializer for Serializer<'a> {
34    type Ok = Term<'a>;
35    type Error = Error;
36
37    type SerializeSeq = SequenceSerializer<'a>;
38    type SerializeTuple = SequenceSerializer<'a>;
39    type SerializeTupleStruct = SequenceSerializer<'a>;
40    type SerializeTupleVariant = SequenceSerializer<'a>;
41    type SerializeMap = MapSerializer<'a>;
42    type SerializeStruct = MapSerializer<'a>;
43    type SerializeStructVariant = MapSerializer<'a>;
44
45    #[inline]
46    fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
47        Ok(v.encode(self.env))
48    }
49
50    #[inline]
51    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
52        Ok(atoms::nil().encode(self.env))
53    }
54
55    #[inline]
56    fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
57    where
58        T: ?Sized + ser::Serialize,
59    {
60        value.serialize(self)
61    }
62
63    #[inline]
64    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
65        Ok(v.encode(self.env))
66    }
67
68    #[inline]
69    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
70        Ok(v.encode(self.env))
71    }
72
73    #[inline]
74    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
75        Ok(v.encode(self.env))
76    }
77
78    #[inline]
79    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
80        Ok(v.encode(self.env))
81    }
82
83    #[inline]
84    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
85        Ok(v.encode(self.env))
86    }
87
88    #[inline]
89    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
90        Ok(v.encode(self.env))
91    }
92
93    #[inline]
94    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
95        Ok(v.encode(self.env))
96    }
97
98    #[inline]
99    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
100        Ok(v.encode(self.env))
101    }
102
103    #[inline]
104    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
105        Ok(v.encode(self.env))
106    }
107
108    #[inline]
109    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
110        if !v.is_finite() {
111            return if self.non_finite_float_as_atom {
112                if v.is_nan() {
113                    Ok(atoms::nan().encode(self.env))
114                } else if v.is_sign_positive() {
115                    Ok(atoms::inf().encode(self.env))
116                } else {
117                    Ok(atoms::neg_inf().encode(self.env))
118                }
119            } else {
120                Err(Error::NonFiniteFloat)
121            };
122        }
123
124        Ok(v.encode(self.env))
125    }
126
127    fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
128        Ok(v.encode(self.env))
129    }
130
131    fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
132        Ok(v.encode(self.env))
133    }
134
135    #[inline]
136    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
137        let mut ser: SequenceSerializer = self.serialize_seq(Some(1))?;
138        ser::SerializeSeq::serialize_element(&mut ser, &(v as u32))?;
139        ser::SerializeSeq::end(ser)
140    }
141
142    #[inline]
143    fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
144        let env = self.env;
145        let str_len = v.len();
146        let mut bin = match OwnedBinary::new(str_len) {
147            Some(bin) => bin,
148            None => panic!("binary term allocation fail"),
149        };
150        bin.as_mut_slice()
151            .write_all(v.as_bytes())
152            .expect("memory copy of string failed");
153        Ok(bin.release(env).to_term(env))
154    }
155
156    #[inline]
157    fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
158        let mut binary = OwnedBinary::new(v.len()).unwrap();
159        binary
160            .as_mut_slice()
161            .write_all(v)
162            .or(Err(Error::InvalidBinary))?;
163        Ok(binary.release(self.env).to_term(self.env))
164    }
165
166    /// Serializes unit (empty tuple) as `nil`.
167    #[inline]
168    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
169        Ok(atoms::nil().to_term(self.env))
170    }
171
172    #[inline]
173    /// Serializes `struct Unit` as `nil`.
174    fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
175        self.serialize_unit()
176    }
177
178    #[inline]
179    /// Serializes `E::A` in `enum E { A, B }` as `:A` or `"A"`, depending on
180    /// if the atom `:A` has already been created.
181    fn serialize_unit_variant(
182        self,
183        _name: &'static str,
184        _variant_index: u32,
185        variant: &'static str,
186    ) -> Result<Self::Ok, Self::Error> {
187        atoms::str_to_term(&self.env, variant).or(Err(Error::InvalidVariantName))
188    }
189
190    #[inline]
191    /// Serializes `struct Millimeters(u8)` as a tagged tuple:
192    /// `{:Millimeters, u8}` or `{"Millimeters", u8}`, depending on if the atom
193    /// `:Millimeters` has already been created.
194    fn serialize_newtype_struct<T>(
195        self,
196        name: &'static str,
197        value: &T,
198    ) -> Result<Self::Ok, Self::Error>
199    where
200        T: ?Sized + ser::Serialize,
201    {
202        let name_term = atoms::str_to_term(&self.env, name).or(Err(Error::InvalidVariantName))?;
203        let mut ser = SequenceSerializer::new(self, Some(2), Some(name_term));
204        ser.add(value.serialize(self)?);
205        ser.to_tuple()
206    }
207
208    #[inline]
209    /// Serializes `E::N` in `enum E { N(u8) }` as a tagged tuple: `{:N, u8}`
210    /// or `{"N", u8}`, depending on if the atom `:N` has already been created.
211    /// Serializes `Result::Ok` and `Result::Err` of
212    /// `enum Result { Ok(u8), Err(_) }` into `{:ok, u8}` or `{:err, _}`.
213    fn serialize_newtype_variant<T>(
214        self,
215        name: &'static str,
216        _variant_index: u32,
217        variant: &'static str,
218        value: &T,
219    ) -> Result<Self::Ok, Self::Error>
220    where
221        T: ?Sized + ser::Serialize,
222    {
223        match (name, variant) {
224            ("Result", "Ok") => self.serialize_newtype_struct("ok", value),
225            ("Result", "Err") => self.serialize_newtype_struct("error", value),
226            _ => self.serialize_newtype_struct(variant, value),
227        }
228    }
229
230    #[inline]
231    /// Serializes sequences as a Elixir lists.
232    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
233        Ok(SequenceSerializer::new(self, len, None))
234    }
235
236    #[inline]
237    /// Serializes tuples as Elixir tuples.
238    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
239        Ok(SequenceSerializer::new(self, Some(len), None))
240    }
241
242    #[inline]
243    /// Serializes `struct Rgb(u8, u8, u8)` as an Elixir Record or Record-like
244    /// tuple: `{:Rgb, u8, u8, u8}` or `{"Rgb", u8, u8, u8}`.
245    fn serialize_tuple_struct(
246        self,
247        name: &'static str,
248        len: usize,
249    ) -> Result<Self::SerializeTupleStruct, Self::Error> {
250        let name_term = atoms::str_to_term(&self.env, name).or(Err(Error::InvalidVariantName))?;
251        Ok(SequenceSerializer::new(self, Some(len), Some(name_term)))
252    }
253
254    #[inline]
255    /// Serializes `E::T` of `enum E { T(u8, u8) }` as an Elixir Record or Record-like tuple: `{:T, u8, u8}` or `{"T", u8, u8}`.
256    fn serialize_tuple_variant(
257        self,
258        _name: &'static str,
259        _variant_index: u32,
260        variant: &'static str,
261        len: usize,
262    ) -> Result<Self::SerializeTupleVariant, Self::Error> {
263        self.serialize_tuple_struct(variant, len)
264    }
265
266    #[inline]
267    /// Serializes map as Elixir map. Keys *will not* serialize into atoms.
268    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
269        Ok(MapSerializer::new(self, len, None))
270    }
271
272    #[inline]
273    /// Serializes as map, but attempts to include
274    /// `%{:__struct__ => :STRUCT_NAME}` or `${:__struct__ => "STRUCT_NAME"}`,
275    /// if the atom `:STRUCT_NAME` has not already been created, and will also
276    /// attempt to serialize keys as atoms.
277    fn serialize_struct(
278        self,
279        name: &'static str,
280        len: usize,
281    ) -> Result<Self::SerializeStruct, Self::Error> {
282        let name_term = util::str_to_term(&self.env, name).or(Err(Error::InvalidStructName))?;
283        Ok(MapSerializer::new(self, Some(len), Some(name_term)))
284    }
285
286    #[inline]
287    /// Serializes the same as we serialize a struct: `E::S` of
288    /// `enum E { S { r: u8, g: u8, b: u8 } }` is a map including
289    /// `%{:__struct__ => :S}` or `${:__struct__ => "S"}`.
290    fn serialize_struct_variant(
291        self,
292        _name: &'static str,
293        _variant_index: u32,
294        variant: &'static str,
295        len: usize,
296    ) -> Result<Self::SerializeStructVariant, Self::Error> {
297        self.serialize_struct(variant, len)
298    }
299}
300
301/// SequenceSerializer
302pub struct SequenceSerializer<'a> {
303    ser: Serializer<'a>,
304    items: Vec<Term<'a>>,
305}
306impl<'a> SequenceSerializer<'a> {
307    #[inline]
308    fn new(ser: Serializer<'a>, len: Option<usize>, name: Option<Term<'a>>) -> Self {
309        let mut items = match len {
310            None => Vec::new(),
311            Some(length) => Vec::with_capacity(length),
312        };
313
314        if let Some(name_term) = name {
315            items.push(name_term);
316        }
317
318        SequenceSerializer { ser, items }
319    }
320
321    #[inline]
322    fn add(&mut self, term: Term<'a>) {
323        self.items.push(term)
324    }
325
326    #[inline]
327    fn to_list(&self) -> Result<Term<'a>, Error> {
328        let env = self.ser.env;
329        let term_array: Vec<_> = self
330            .items
331            .iter()
332            .map(|x| x.encode(env).as_c_arg())
333            .collect();
334        unsafe { Ok(Term::new(env, make_list(env.as_c_arg(), &term_array))) }
335    }
336
337    #[inline]
338    fn to_tuple(&self) -> Result<Term<'a>, Error> {
339        Ok(tuple::make_tuple(self.ser.env, &self.items))
340    }
341}
342
343impl<'a> ser::SerializeSeq for SequenceSerializer<'a> {
344    type Ok = Term<'a>;
345    type Error = Error;
346
347    #[inline]
348    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
349    where
350        T: ?Sized + Serialize,
351    {
352        self.add(value.serialize(self.ser)?);
353        Ok(())
354    }
355
356    #[inline]
357    fn end(self) -> Result<Term<'a>, Error> {
358        self.to_list()
359    }
360}
361
362impl<'a> ser::SerializeTuple for SequenceSerializer<'a> {
363    type Ok = Term<'a>;
364    type Error = Error;
365
366    #[inline]
367    fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
368    where
369        T: ?Sized + Serialize,
370    {
371        self.add(value.serialize(self.ser)?);
372        Ok(())
373    }
374
375    #[inline]
376    fn end(self) -> Result<Term<'a>, Error> {
377        self.to_tuple()
378    }
379}
380
381impl<'a> ser::SerializeTupleStruct for SequenceSerializer<'a> {
382    type Ok = Term<'a>;
383    type Error = Error;
384
385    #[inline]
386    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
387    where
388        T: ?Sized + Serialize,
389    {
390        ser::SerializeTuple::serialize_element(self, value)
391    }
392
393    #[inline]
394    fn end(self) -> Result<Term<'a>, Error> {
395        ser::SerializeTuple::end(self)
396    }
397}
398
399impl<'a> ser::SerializeTupleVariant for SequenceSerializer<'a> {
400    type Ok = Term<'a>;
401    type Error = Error;
402
403    #[inline]
404    fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
405    where
406        T: ?Sized + Serialize,
407    {
408        ser::SerializeTuple::serialize_element(self, value)
409    }
410
411    #[inline]
412    fn end(self) -> Result<Term<'a>, Error> {
413        ser::SerializeTuple::end(self)
414    }
415}
416
417/// MapSerializer
418pub struct MapSerializer<'a> {
419    ser: Serializer<'a>,
420    name: Option<Term<'a>>,
421    keys: Vec<Term<'a>>,
422    values: Vec<Term<'a>>,
423}
424impl<'a> MapSerializer<'a> {
425    #[inline]
426    fn new(ser: Serializer<'a>, len: Option<usize>, name: Option<Term<'a>>) -> Self {
427        match len {
428            None => MapSerializer {
429                ser,
430                name,
431                keys: Vec::new(),
432                values: Vec::new(),
433            },
434            Some(length) => MapSerializer {
435                ser,
436                name,
437                keys: Vec::with_capacity(length),
438                values: Vec::with_capacity(length),
439            },
440        }
441    }
442
443    #[inline]
444    fn add_key(&mut self, term: Term<'a>) {
445        if self.keys.len() == self.values.len() {
446            self.keys.push(term)
447        } else {
448            panic!("MapSerializer.serialize_key was called twice in a row")
449        }
450    }
451
452    #[inline]
453    fn add_val(&mut self, term: Term<'a>) {
454        if self.keys.len() == self.values.len() + 1 {
455            self.values.push(term)
456        } else {
457            panic!("MapSerializer.serialize_value was called incorrectly")
458        }
459    }
460
461    #[inline]
462    fn to_map(&self) -> Result<Term<'a>, Error> {
463        Term::map_from_arrays(self.ser.env, &self.keys, &self.values).or(Err(Error::InvalidMap))
464    }
465
466    #[inline]
467    fn to_struct(&self) -> Result<Term<'a>, Error> {
468        let struct_atom = atoms::__struct__().to_term(self.ser.env);
469        let module_term = self.name.ok_or(Error::ExpectedStructName)?;
470        self.to_map()
471            .or(Err(Error::InvalidStruct))?
472            .map_put(struct_atom, module_term)
473            .or(Err(Error::InvalidStruct))
474    }
475}
476
477impl<'a> ser::SerializeMap for MapSerializer<'a> {
478    type Ok = Term<'a>;
479    type Error = Error;
480
481    #[inline]
482    fn serialize_key<T>(&mut self, key: &T) -> Result<(), Error>
483    where
484        T: ?Sized + Serialize,
485    {
486        self.add_key(key.serialize(self.ser)?);
487        Ok(())
488    }
489
490    #[inline]
491    fn serialize_value<T>(&mut self, value: &T) -> Result<(), Error>
492    where
493        T: ?Sized + Serialize,
494    {
495        self.add_val(value.serialize(self.ser)?);
496        Ok(())
497    }
498
499    fn end(self) -> Result<Term<'a>, Error> {
500        self.to_map()
501    }
502}
503
504impl<'a> ser::SerializeStruct for MapSerializer<'a> {
505    type Ok = Term<'a>;
506    type Error = Error;
507
508    #[inline]
509    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
510    where
511        T: ?Sized + Serialize,
512    {
513        let key_term = atoms::str_to_term(&self.ser.env, key).or(Err(Error::InvalidStructKey))?;
514        self.add_key(key_term);
515        self.add_val(value.serialize(self.ser)?);
516        Ok(())
517    }
518
519    fn end(self) -> Result<Term<'a>, Error> {
520        self.to_struct()
521    }
522}
523
524impl<'a> ser::SerializeStructVariant for MapSerializer<'a> {
525    type Ok = Term<'a>;
526    type Error = Error;
527
528    #[inline]
529    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
530    where
531        T: ?Sized + Serialize,
532    {
533        ser::SerializeStruct::serialize_field(self, key, value)
534    }
535
536    fn end(self) -> Result<Term<'a>, Error> {
537        ser::SerializeStruct::end(self)
538    }
539}