diff --git a/src/de.rs b/src/de.rs index ed35f73..064f77d 100644 --- a/src/de.rs +++ b/src/de.rs @@ -27,7 +27,7 @@ impl<'de> de::SeqAccess<'de> for SeqAccess { } } -/// Provides [`serde::de::MapAccess`] from any JS iterator that returns `[key, value]` pairs. +/// Provides [`de::MapAccess`] from any JS iterator that returns `[key, value]` pairs. struct MapAccess { iter: js_sys::IntoIter, next_value: Option, @@ -143,7 +143,7 @@ impl<'de> de::SeqAccess<'de> for PreservedValueAccess { } } -/// Provides [`serde::de::EnumAccess`] from given JS values for the `tag` and the `payload`. +/// Provides [`de::EnumAccess`] from given JS values for the `tag` and the `payload`. struct EnumAccess { tag: Deserializer, payload: Deserializer, @@ -161,7 +161,7 @@ impl<'de> de::EnumAccess<'de> for EnumAccess { } } -/// A newtype that allows using any [`JsValue`] as a [`serde::Deserializer`]. +/// A newtype that allows using any [`JsValue`] as a [`deserializer`]. pub struct Deserializer { value: JsValue, } @@ -189,8 +189,6 @@ fn convert_pair(pair: JsValue) -> (Deserializer, Deserializer) { } impl Deserializer { - /// Casts the internal value into an object, including support for prototype-less objects. - /// See https://github.com/rustwasm/wasm-bindgen/issues/1366 for why we don't use `dyn_ref`. fn as_object_entries(&self) -> Option { if self.value.is_object() { Some(Object::entries(self.value.unchecked_ref())) @@ -415,6 +413,9 @@ impl<'de> de::Deserializer<'de> for Deserializer { self.deserialize_from_js_number_unsigned(visitor) } + /// Supported inputs: + /// - `BigInt` within `i64` boundaries. + /// - number within safe integer boundaries. fn deserialize_i64>(self, visitor: V) -> Result { if self.value.is_bigint() { match i64::try_from(self.value) { @@ -428,6 +429,9 @@ impl<'de> de::Deserializer<'de> for Deserializer { } } + /// Supported inputs: + /// - `BigInt` within `u64` boundaries. + /// - number within safe integer boundaries. fn deserialize_u64>(self, visitor: V) -> Result { if self.value.is_bigint() { match u64::try_from(self.value) { @@ -441,6 +445,8 @@ impl<'de> de::Deserializer<'de> for Deserializer { } } + /// Supported inputs: + /// - `BigInt` within `i128` boundaries. fn deserialize_i128>(self, visitor: V) -> Result { if self.value.is_bigint() { match i128::try_from(self.value) { @@ -454,6 +460,8 @@ impl<'de> de::Deserializer<'de> for Deserializer { } } + /// Supported inputs: + /// - `BigInt` within `u128` boundaries. fn deserialize_u128>(self, visitor: V) -> Result { if self.value.is_bigint() { match u128::try_from(self.value) { @@ -467,7 +475,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { } } - /// Converts a JavaScript string to a Rust char. + /// Converts a JavaScript string to a Rust `char`. /// /// By default we don't perform detection of single chars because it's pretty complicated, /// but if we get a hint that they're expected, this methods allows to avoid heap allocations @@ -481,6 +489,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { self.invalid_type(visitor) } + /// Deserializes `undefined` or `null` into `None` and any other value into `Some(value)`. // Serde can deserialize `visit_unit` into `None`, but can't deserialize arbitrary value // as `Some`, so we need to provide own simple implementation. fn deserialize_option>(self, visitor: V) -> Result { @@ -491,7 +500,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { } } - /// Simply calls `visit_newtype_struct`. + /// Forwards to deserializing newtype contents. fn deserialize_newtype_struct>( self, _name: &'static str, @@ -502,6 +511,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { /// Supported inputs: /// - JS iterable (an object with [`[Symbol.iterator]`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator)). + /// /// Supported outputs: /// - Any Rust sequence from Serde point of view ([`Vec`], [`HashSet`](std::collections::HashSet), etc.) fn deserialize_seq>(self, visitor: V) -> Result { @@ -535,6 +545,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { /// Supported inputs: /// - A JS iterable that is expected to return `[key, value]` pairs. /// - A JS object, which will be iterated using [`Object.entries`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries). + /// /// Supported outputs: /// - A Rust key-value map ([`HashMap`](std::collections::HashMap), [`BTreeMap`](std::collections::BTreeMap), etc.). /// - A typed Rust structure with `#[derive(Deserialize)]`. @@ -550,6 +561,7 @@ impl<'de> de::Deserializer<'de> for Deserializer { /// Supported inputs: /// - A plain JS object. + /// /// Supported outputs: /// - A typed Rust structure with `#[derive(Deserialize)]`. fn deserialize_struct>( diff --git a/src/ser.rs b/src/ser.rs index 32f5b7f..708a651 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -10,14 +10,15 @@ use crate::{static_str_to_js, Error, ObjectExt}; type Result = super::Result; /// Wraps other serializers into an enum tagged variant form. -/// Uses {"Variant": ...payload...} for compatibility with serde-json. +/// +/// Results in `{"Variant": ...payload...}` for compatibility with serde-json. pub struct VariantSerializer { variant: &'static str, inner: S, } impl VariantSerializer { - pub const fn new(variant: &'static str, inner: S) -> Self { + const fn new(variant: &'static str, inner: S) -> Self { Self { variant, inner } } @@ -64,6 +65,7 @@ impl> ser::SerializeStructV } } +/// Serializes Rust iterables and tuples into JS arrays. pub struct ArraySerializer<'s> { serializer: &'s Serializer, target: Array, @@ -71,7 +73,7 @@ pub struct ArraySerializer<'s> { } impl<'s> ArraySerializer<'s> { - pub fn new(serializer: &'s Serializer) -> Self { + fn new(serializer: &'s Serializer) -> Self { Self { serializer, target: Array::new(), @@ -126,6 +128,10 @@ pub enum MapResult { Object(Object), } +/// Serializes Rust maps into JS `Map` or plain JS objects. +/// +/// Plain JS objects are used if `serialize_maps_as_objects` is set to `true`, +/// but then only string keys are supported. pub struct MapSerializer<'s> { serializer: &'s Serializer, target: MapResult, @@ -182,6 +188,7 @@ impl ser::SerializeMap for MapSerializer<'_> { } } +/// Serializes Rust structs into plain JS objects. pub struct ObjectSerializer<'s> { serializer: &'s Serializer, target: ObjectExt, @@ -314,6 +321,11 @@ impl<'s> ser::Serializer for &'s Serializer { serialize_str(&str); } + /// Serializes `i64` into a `BigInt` or a JS number. + /// + /// If `serialize_large_number_types_as_bigints` is set to `false`, + /// `i64` is serialized as a JS number. But in this mode only numbers + /// within the safe integer range are supported. fn serialize_i64(self, v: i64) -> Result { if self.serialize_large_number_types_as_bigints { return Ok(v.into()); @@ -334,6 +346,11 @@ impl<'s> ser::Serializer for &'s Serializer { } } + /// Serializes `u64` into a `BigInt` or a JS number. + /// + /// If `serialize_large_number_types_as_bigints` is set to `false`, + /// `u64` is serialized as a JS number. But in this mode only numbers + /// within the safe integer range are supported. fn serialize_u64(self, v: u64) -> Result { if self.serialize_large_number_types_as_bigints { return Ok(v.into()); @@ -349,18 +366,24 @@ impl<'s> ser::Serializer for &'s Serializer { } } + /// Serializes `i128` into a `BigInt`. fn serialize_i128(self, v: i128) -> Result { Ok(JsValue::from(v)) } + /// Serializes `u128` into a `BigInt`. fn serialize_u128(self, v: u128) -> Result { Ok(JsValue::from(v)) } + /// Serializes `char` into a JS string. fn serialize_char(self, v: char) -> Result { Ok(JsString::from(v).into()) } + /// Serializes `bytes` into a JS `Uint8Array` or a plain JS array. + /// + /// If `serialize_bytes_as_arrays` is set to `true`, bytes are serialized as plain JS arrays. fn serialize_bytes(self, v: &[u8]) -> Result { // Create a `Uint8Array` view into a Rust slice, and immediately copy it to the JS memory. // @@ -374,14 +397,21 @@ impl<'s> ser::Serializer for &'s Serializer { } } + /// Serializes `None` into `undefined` or `null`. + /// + /// If `serialize_missing_as_null` is set to `true`, `None` is serialized as `null`. fn serialize_none(self) -> Result { self.serialize_unit() } + /// Serializes `Some(T)` as `T`. fn serialize_some(self, value: &T) -> Result { value.serialize(self) } + /// Serializes `()` into `undefined` or `null`. + /// + /// If `serialize_missing_as_null` is set to `true`, `()` is serialized as `null`. fn serialize_unit(self) -> Result { Ok(if self.serialize_missing_as_null { JsValue::NULL @@ -390,11 +420,12 @@ impl<'s> ser::Serializer for &'s Serializer { }) } + /// Serializes unit structs into `undefined` or `null`. fn serialize_unit_struct(self, _name: &'static str) -> Result { self.serialize_unit() } - /// For compatibility with serde-json, serialises unit variants as "Variant" strings. + /// For compatibility with serde-json, sserializes unit variants as "Variant" strings. fn serialize_unit_variant( self, _name: &'static str, @@ -404,6 +435,7 @@ impl<'s> ser::Serializer for &'s Serializer { Ok(static_str_to_js(variant).into()) } + /// Serializes newtype structs as their inner values. fn serialize_newtype_struct( self, name: &'static str, @@ -419,6 +451,7 @@ impl<'s> ser::Serializer for &'s Serializer { value.serialize(self) } + /// Serializes newtype variants as their inner values. fn serialize_newtype_variant( self, _name: &'static str, @@ -429,16 +462,18 @@ impl<'s> ser::Serializer for &'s Serializer { VariantSerializer::new(variant, self.serialize_newtype_struct(variant, value)?).end(Ok) } - /// Serialises any Rust iterable into a JS Array. - // TODO: Figure out if there is a way to detect and serialise `Set` differently. + /// Sserializes any Rust iterable as a JS Array. + // TODO: Figure out if there is a way to detect and sserialize `Set` differently. fn serialize_seq(self, _len: Option) -> Result { Ok(ArraySerializer::new(self)) } + /// Sserializes Rust tuples as JS arrays. fn serialize_tuple(self, len: usize) -> Result { self.serialize_seq(Some(len)) } + /// Sserializes Rust tuple structs as JS arrays. fn serialize_tuple_struct( self, _name: &'static str, @@ -447,6 +482,7 @@ impl<'s> ser::Serializer for &'s Serializer { self.serialize_tuple(len) } + /// Sserializes Rust tuple variants as `{"Variant": [ ...tuple... ]}`. fn serialize_tuple_variant( self, _name: &'static str, @@ -460,16 +496,19 @@ impl<'s> ser::Serializer for &'s Serializer { )) } - /// Serialises Rust maps into JS `Map` or plain JS objects, depending on configuration of `serialize_maps_as_objects`. + /// Sserializes Rust maps into JS `Map` or plain JS objects. + /// + /// See [`MapSerializer`] for more details. fn serialize_map(self, _len: Option) -> Result { Ok(MapSerializer::new(self, self.serialize_maps_as_objects)) } - /// Serialises Rust typed structs into plain JS objects. + /// Sserializes Rust typed structs into plain JS objects. fn serialize_struct(self, _name: &'static str, _len: usize) -> Result { Ok(ObjectSerializer::new(self)) } + /// Sserializes Rust struct-like variants into `{"Variant": { ...fields... }}`. fn serialize_struct_variant( self, _name: &'static str, diff --git a/tests/common/mod.rs b/tests/common/mod.rs index f5a56b2..e9747db 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -736,7 +736,7 @@ fn sequences() { test_via_json((100, "xyz".to_string(), true)); // Sets are currently indistinguishable from other sequences for - // Serde serialisers, so this will become an array on the JS side. + // Serde sserializers, so this will become an array on the JS side. test_via_json(hashset! {false, true}); }