napi_calm_down/js_values/
ser.rs

1use std::result::Result as StdResult;
2#[cfg(feature = "napi6")]
3use std::slice;
4
5use serde::{ser, Serialize, Serializer};
6
7use super::*;
8use crate::{Env, Error, Result};
9
10pub struct Ser<'env>(pub(crate) &'env Env);
11
12impl<'env> Ser<'env> {
13  pub fn new(env: &'env Env) -> Self {
14    Self(env)
15  }
16}
17
18impl<'env> Serializer for Ser<'env> {
19  type Ok = Value;
20  type Error = Error;
21
22  type SerializeSeq = SeqSerializer;
23  type SerializeTuple = SeqSerializer;
24  type SerializeTupleStruct = SeqSerializer;
25  type SerializeTupleVariant = SeqSerializer;
26  type SerializeMap = MapSerializer;
27  type SerializeStruct = StructSerializer;
28  type SerializeStructVariant = StructSerializer;
29
30  fn serialize_bool(self, v: bool) -> Result<Self::Ok> {
31    self.0.get_boolean(v).map(|js_value| js_value.0)
32  }
33
34  fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok> {
35    self
36      .0
37      .create_buffer_with_data(v.to_owned())
38      .map(|js_value| js_value.value.0)
39  }
40
41  fn serialize_char(self, v: char) -> Result<Self::Ok> {
42    let mut b = [0; 4];
43    let result = v.encode_utf8(&mut b);
44    self.0.create_string(result).map(|js_string| js_string.0)
45  }
46
47  fn serialize_f32(self, v: f32) -> Result<Self::Ok> {
48    self.0.create_double(v as _).map(|js_number| js_number.0)
49  }
50
51  fn serialize_f64(self, v: f64) -> Result<Self::Ok> {
52    self.0.create_double(v).map(|js_number| js_number.0)
53  }
54
55  fn serialize_i16(self, v: i16) -> Result<Self::Ok> {
56    self.0.create_int32(v as _).map(|js_number| js_number.0)
57  }
58
59  fn serialize_i32(self, v: i32) -> Result<Self::Ok> {
60    self.0.create_int32(v).map(|js_number| js_number.0)
61  }
62
63  fn serialize_i64(self, v: i64) -> Result<Self::Ok> {
64    self.0.create_int64(v).map(|js_number| js_number.0)
65  }
66
67  fn serialize_i8(self, v: i8) -> Result<Self::Ok> {
68    self.0.create_int32(v as _).map(|js_number| js_number.0)
69  }
70
71  fn serialize_u8(self, v: u8) -> Result<Self::Ok> {
72    self.0.create_uint32(v as _).map(|js_number| js_number.0)
73  }
74
75  fn serialize_u16(self, v: u16) -> Result<Self::Ok> {
76    self.0.create_uint32(v as _).map(|js_number| js_number.0)
77  }
78
79  fn serialize_u32(self, v: u32) -> Result<Self::Ok> {
80    self.0.create_uint32(v).map(|js_number| js_number.0)
81  }
82
83  #[cfg(all(
84    any(
85      feature = "napi2",
86      feature = "napi3",
87      feature = "napi4",
88      feature = "napi5"
89    ),
90    not(feature = "napi6")
91  ))]
92  fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
93    self.0.create_int64(v as _).map(|js_number| js_number.0)
94  }
95
96  #[cfg(feature = "napi6")]
97  fn serialize_u64(self, v: u64) -> Result<Self::Ok> {
98    // https://github.com/napi-rs/napi-rs/issues/1470
99    // serde_json::Value by default uses u64 for positive integers. This results in napirs using a BigInt instead of a number when converting to a js value.
100    // To avoid this, we need to check if the value fits into a smaller number type.
101    // If this is the case, we use the smaller type instead.
102    if v <= u32::MAX.into() {
103      self.serialize_u32(v as u32)
104    } else {
105      self
106        .0
107        .create_bigint_from_u64(v)
108        .map(|js_number| js_number.raw)
109    }
110  }
111
112  #[cfg(all(
113    any(
114      feature = "napi2",
115      feature = "napi3",
116      feature = "napi4",
117      feature = "napi5"
118    ),
119    not(feature = "napi6")
120  ))]
121  fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
122    self.0.create_string(v.to_string().as_str()).map(|v| v.0)
123  }
124
125  #[cfg(feature = "napi6")]
126  fn serialize_u128(self, v: u128) -> Result<Self::Ok> {
127    let words_ref = &v as *const _;
128    let words = unsafe { slice::from_raw_parts(words_ref as *const u64, 2) };
129    self
130      .0
131      .create_bigint_from_words(false, words.to_vec())
132      .map(|v| v.raw)
133  }
134
135  #[cfg(all(
136    any(
137      feature = "napi2",
138      feature = "napi3",
139      feature = "napi4",
140      feature = "napi5"
141    ),
142    not(feature = "napi6")
143  ))]
144  fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
145    self.0.create_string(v.to_string().as_str()).map(|v| v.0)
146  }
147
148  #[cfg(feature = "napi6")]
149  fn serialize_i128(self, v: i128) -> Result<Self::Ok> {
150    let words_ref = &(v as u128) as *const _;
151    let words = unsafe { slice::from_raw_parts(words_ref as *const u64, 2) };
152    self
153      .0
154      .create_bigint_from_words(v < 0, words.to_vec())
155      .map(|v| v.raw)
156  }
157
158  fn serialize_unit(self) -> Result<Self::Ok> {
159    self.0.get_null().map(|null| null.0)
160  }
161
162  fn serialize_none(self) -> Result<Self::Ok> {
163    self.0.get_null().map(|null| null.0)
164  }
165
166  fn serialize_str(self, v: &str) -> Result<Self::Ok> {
167    self.0.create_string(v).map(|string| string.0)
168  }
169
170  fn serialize_some<T>(self, value: &T) -> Result<Self::Ok>
171  where
172    T: ?Sized + Serialize,
173  {
174    value.serialize(self)
175  }
176
177  fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
178    let env = self.0;
179    let key = env.create_string("")?;
180    let obj = env.create_object()?;
181    Ok(MapSerializer { key, obj })
182  }
183
184  fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
185    let array = self.0.create_array_with_length(len.unwrap_or(0))?;
186    Ok(SeqSerializer {
187      current_index: 0,
188      array,
189    })
190  }
191
192  fn serialize_tuple_variant(
193    self,
194    _name: &'static str,
195    _variant_index: u32,
196    variant: &'static str,
197    len: usize,
198  ) -> Result<Self::SerializeTupleVariant> {
199    let env = self.0;
200    let array = env.create_array_with_length(len)?;
201    let mut object = env.create_object()?;
202    object.set_named_property(
203      variant,
204      JsObject(Value {
205        value: array.0.value,
206        env: array.0.env,
207        value_type: ValueType::Object,
208      }),
209    )?;
210    Ok(SeqSerializer {
211      current_index: 0,
212      array,
213    })
214  }
215
216  fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok> {
217    self.0.get_null().map(|null| null.0)
218  }
219
220  fn serialize_unit_variant(
221    self,
222    _name: &'static str,
223    _variant_index: u32,
224    variant: &'static str,
225  ) -> Result<Self::Ok> {
226    self.0.create_string(variant).map(|string| string.0)
227  }
228
229  fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Self::Ok>
230  where
231    T: ?Sized + Serialize,
232  {
233    value.serialize(self)
234  }
235
236  fn serialize_newtype_variant<T>(
237    self,
238    _name: &'static str,
239    _variant_index: u32,
240    variant: &'static str,
241    value: &T,
242  ) -> Result<Self::Ok>
243  where
244    T: ?Sized + Serialize,
245  {
246    let mut obj = self.0.create_object()?;
247    obj.set_named_property(variant, JsUnknown(value.serialize(self)?))?;
248    Ok(obj.0)
249  }
250
251  fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
252    Ok(SeqSerializer {
253      array: self.0.create_array_with_length(len)?,
254      current_index: 0,
255    })
256  }
257
258  fn serialize_tuple_struct(
259    self,
260    _name: &'static str,
261    len: usize,
262  ) -> Result<Self::SerializeTupleStruct> {
263    Ok(SeqSerializer {
264      array: self.0.create_array_with_length(len)?,
265      current_index: 0,
266    })
267  }
268
269  fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
270    Ok(StructSerializer {
271      obj: self.0.create_object()?,
272    })
273  }
274
275  fn serialize_struct_variant(
276    self,
277    _name: &'static str,
278    _variant_index: u32,
279    variant: &'static str,
280    _len: usize,
281  ) -> Result<Self::SerializeStructVariant> {
282    let mut outer = self.0.create_object()?;
283    let inner = self.0.create_object()?;
284    outer.set_named_property(
285      variant,
286      JsObject(Value {
287        env: inner.0.env,
288        value: inner.0.value,
289        value_type: ValueType::Object,
290      }),
291    )?;
292    Ok(StructSerializer {
293      obj: self.0.create_object()?,
294    })
295  }
296}
297
298pub struct SeqSerializer {
299  array: JsObject,
300  current_index: usize,
301}
302
303impl ser::SerializeSeq for SeqSerializer {
304  type Ok = Value;
305  type Error = Error;
306
307  fn serialize_element<T>(&mut self, value: &T) -> StdResult<(), Self::Error>
308  where
309    T: ?Sized + Serialize,
310  {
311    let env = unsafe { Env::from_raw(self.array.0.env) };
312    self.array.set_element(
313      self.current_index as _,
314      JsUnknown(value.serialize(Ser::new(&env))?),
315    )?;
316    self.current_index += 1;
317    Ok(())
318  }
319
320  fn end(self) -> Result<Self::Ok> {
321    Ok(self.array.0)
322  }
323}
324
325#[doc(hidden)]
326impl ser::SerializeTuple for SeqSerializer {
327  type Ok = Value;
328  type Error = Error;
329
330  fn serialize_element<T>(&mut self, value: &T) -> StdResult<(), Self::Error>
331  where
332    T: ?Sized + Serialize,
333  {
334    let env = unsafe { Env::from_raw(self.array.0.env) };
335    self.array.set_element(
336      self.current_index as _,
337      JsUnknown(value.serialize(Ser::new(&env))?),
338    )?;
339    self.current_index += 1;
340    Ok(())
341  }
342
343  fn end(self) -> StdResult<Self::Ok, Self::Error> {
344    Ok(self.array.0)
345  }
346}
347
348#[doc(hidden)]
349impl ser::SerializeTupleStruct for SeqSerializer {
350  type Ok = Value;
351  type Error = Error;
352
353  fn serialize_field<T>(&mut self, value: &T) -> StdResult<(), Self::Error>
354  where
355    T: ?Sized + Serialize,
356  {
357    let env = unsafe { Env::from_raw(self.array.0.env) };
358    self.array.set_element(
359      self.current_index as _,
360      JsUnknown(value.serialize(Ser::new(&env))?),
361    )?;
362    self.current_index += 1;
363    Ok(())
364  }
365
366  fn end(self) -> StdResult<Self::Ok, Self::Error> {
367    Ok(self.array.0)
368  }
369}
370
371#[doc(hidden)]
372impl ser::SerializeTupleVariant for SeqSerializer {
373  type Ok = Value;
374  type Error = Error;
375
376  fn serialize_field<T>(&mut self, value: &T) -> StdResult<(), Self::Error>
377  where
378    T: ?Sized + Serialize,
379  {
380    let env = unsafe { Env::from_raw(self.array.0.env) };
381    self.array.set_element(
382      self.current_index as _,
383      JsUnknown(value.serialize(Ser::new(&env))?),
384    )?;
385    self.current_index += 1;
386    Ok(())
387  }
388
389  fn end(self) -> Result<Self::Ok> {
390    Ok(self.array.0)
391  }
392}
393
394pub struct MapSerializer {
395  key: JsString,
396  obj: JsObject,
397}
398
399#[doc(hidden)]
400impl ser::SerializeMap for MapSerializer {
401  type Ok = Value;
402  type Error = Error;
403
404  fn serialize_key<T>(&mut self, key: &T) -> StdResult<(), Self::Error>
405  where
406    T: ?Sized + Serialize,
407  {
408    let env = unsafe { Env::from_raw(self.obj.0.env) };
409    self.key = JsString(key.serialize(Ser::new(&env))?);
410    Ok(())
411  }
412
413  fn serialize_value<T>(&mut self, value: &T) -> StdResult<(), Self::Error>
414  where
415    T: ?Sized + Serialize,
416  {
417    let env = unsafe { Env::from_raw(self.obj.0.env) };
418    self.obj.set_property(
419      JsString(Value {
420        env: self.key.0.env,
421        value: self.key.0.value,
422        value_type: ValueType::String,
423      }),
424      JsUnknown(value.serialize(Ser::new(&env))?),
425    )?;
426    Ok(())
427  }
428
429  fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> StdResult<(), Self::Error>
430  where
431    K: ?Sized + Serialize,
432    V: ?Sized + Serialize,
433  {
434    let env = unsafe { Env::from_raw(self.obj.0.env) };
435    self.obj.set_property(
436      JsString(key.serialize(Ser::new(&env))?),
437      JsUnknown(value.serialize(Ser::new(&env))?),
438    )?;
439    Ok(())
440  }
441
442  fn end(self) -> Result<Self::Ok> {
443    Ok(self.obj.0)
444  }
445}
446
447pub struct StructSerializer {
448  obj: JsObject,
449}
450
451#[doc(hidden)]
452impl ser::SerializeStruct for StructSerializer {
453  type Ok = Value;
454  type Error = Error;
455
456  fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> StdResult<(), Error>
457  where
458    T: ?Sized + Serialize,
459  {
460    let env = unsafe { Env::from_raw(self.obj.0.env) };
461    self
462      .obj
463      .set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?;
464    Ok(())
465  }
466
467  fn end(self) -> Result<Self::Ok> {
468    Ok(self.obj.0)
469  }
470}
471
472#[doc(hidden)]
473impl ser::SerializeStructVariant for StructSerializer {
474  type Ok = Value;
475  type Error = Error;
476
477  fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> StdResult<(), Error>
478  where
479    T: ?Sized + Serialize,
480  {
481    let env = unsafe { Env::from_raw(self.obj.0.env) };
482    self
483      .obj
484      .set_named_property(key, JsUnknown(value.serialize(Ser::new(&env))?))?;
485    Ok(())
486  }
487
488  fn end(self) -> Result<Self::Ok> {
489    Ok(self.obj.0)
490  }
491}