napi/js_values/
ser.rs

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