diff --git a/.vscode/settings.json b/.vscode/settings.json index f2d37ccb..b017d9bf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,34 +1,40 @@ { "cSpell.words": [ - "Challonge", - "Deque", - "Deserialization", - "Deserializes", - "MSRV", - "Milli", - "NANOS", "accu", + "binhex", "btreemap", "btreeset", "chrono", "clippy", "codecov", "concat", - "datatypes", "datetime", "deps", + "Deque", + "deserializable", + "Deserialization", + "Deserializes", "elems", "fromstr", "hasher", "hashset", "impls", + "indexmap", "linkedlist", + "markazmierczak", + "Milli", + "MSRV", + "NANOS", "newtype", "nsecs", + "rustdoc", + "rustfmt", + "RUSTSEC", "rustversion", "serde", "serde's", "serializable", + "serializers", "struct", "structs", "subsec", @@ -38,6 +44,8 @@ "subsecs", "systemtime", "trybuild", + "Uninit", + "Unpadded", "vecdeque" ], "cSpell.enableFiletypes": [ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1ac67db0..1543d2a8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ Check out the [user guide][user guide] to find out more tips and tricks about this crate. For further help using this crate you can [open a new discussion](https://github.com/jonasbb/serde_with/discussions/new) or ask on [users.rust-lang.org](https://users.rust-lang.org/). -For bugs please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on Github. +For bugs please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on GitHub. ## Reporting Bugs diff --git a/README.md b/README.md index 951c4223..7469634b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Some common use cases are: **Check out the [user guide][user guide] to find out more tips and tricks about this crate.** For further help using this crate you can [open a new discussion](https://github.com/jonasbb/serde_with/discussions/new) or ask on [users.rust-lang.org](https://users.rust-lang.org/). -For bugs please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on Github. +For bugs, please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on GitHub. ## Use `serde_with` in your Project diff --git a/serde_with/src/content/ser.rs b/serde_with/src/content/ser.rs index 97d1ac80..0e8c41c1 100644 --- a/serde_with/src/content/ser.rs +++ b/serde_with/src/content/ser.rs @@ -5,7 +5,7 @@ //! The code is very stable in the `serde` crate, so no maintainability problem is expected. //! //! Since the type is private we copy the type here. -//! `serde` is licences as MIT+Apache2, the same as this crate. +//! `serde` is licensed as MIT+Apache2, the same as this crate. //! //! This version carries improvements compared to `serde`'s version. //! The types support 128-bit integers, which is supported for all targets in Rust 1.40+. diff --git a/serde_with/src/guide.md b/serde_with/src/guide.md index c180d381..9eb80dd9 100644 --- a/serde_with/src/guide.md +++ b/serde_with/src/guide.md @@ -1,6 +1,6 @@ # `serde_with` User Guide -This crate provides helper functions to extend and change how [`serde`] serializes different datatypes. +This crate provides helper functions to extend and change how [`serde`] serializes different data types. For example, you can serialize [a map as a sequence of tuples][crate::guide::serde_as#maps-to-vec-of-tuples], serialize [using the `Display` and `FromStr` traits][`DisplayFromStr`], or serialize [an empty `String` like `None`][NoneAsEmptyString]. `serde_with` covers types from the Rust Standard Library and some common crates like [`chrono`][serde_with_chrono]. @@ -64,7 +64,7 @@ assert_eq!(data, serde_json::from_str(json).unwrap()); ## 2. Integration with serde's with-annotation -[serde's with-annotation][with-annotation] allows to specify a different serialization or deserialization function for a field. +[serde's with-annotation][with-annotation] allows specifying a different serialization or deserialization function for a field. It is useful to adapt the serialization of existing types to the requirements of a protocol. Most modules in this crate can be used together with the with-annotation. @@ -129,7 +129,7 @@ For further details, please refer to the documentation of each proc-macro. ## 4. Derive macros to implement `Deserialize` and `Serialize` -The derive macros work similar to the serde provided ones but they do implement other de/serialization schemes. +The derive macros work similar to the serde provided ones, but they do implement other de/serialization schemes. For example, the derives [`DeserializeFromStr`] and [`SerializeDisplay`] require that the type also implement [`FromStr`] and [`Display`] and de/serializes from/to a string instead of the usual way of iterating over all fields. ## Migrating from the with-annotations to `serde_as` diff --git a/serde_with/src/guide/serde_as.md b/serde_with/src/guide/serde_as.md index 872e9700..76275f00 100644 --- a/serde_with/src/guide/serde_as.md +++ b/serde_with/src/guide/serde_as.md @@ -1,7 +1,7 @@ # `serde_as` Annotation This is an alternative to serde's with-annotation. -It is more flexible and composable but work with fewer types. +It is more flexible and composable, but work with fewer types. The scheme is based on two new traits, [`SerializeAs`] and [`DeserializeAs`], which need to be implemented by all types which want to be compatible with `serde_as`. The proc-macro attribute [`#[serde_as]`][crate::serde_as] exists as a usability boost for users. @@ -20,7 +20,7 @@ This page contains some general advice on the usage of `serde_as` and on impleme ## Switching from serde's with to `serde_as` -For the user the main difference is that instead of +For the user, the main difference is that instead of ```rust,ignore #[serde(with = "...")] @@ -35,7 +35,7 @@ you now have to write and place the `#[serde_as]` attribute *before* the `#[derive]` attribute. You still need the `#[derive(Serialize, Deserialize)]` on the struct/enum. -All together this looks like: +All together, this looks like: ```rust use serde::{Deserialize, Serialize}; @@ -67,7 +67,7 @@ struct A { ### Deserializing Optional Fields -During deserialization serde treats fields of `Option` as optional and does not require them to be present. +During deserialization, serde treats fields of `Option` as optional and does not require them to be present. This breaks when adding either the `serde_as` annotation or serde's `with` annotation. The default behavior can be restored by adding serde's `default` attribute. @@ -85,7 +85,7 @@ struct A { } ``` -In the future this behavior might change and `default` would be applied on `Option` fields. +In the future, this behavior might change and `default` would be applied on `Option` fields. You can add your feedback at [serde_with#185]. ### Gating `serde_as` on Features @@ -103,7 +103,7 @@ struct StructC { ``` The `serde_as` proc-macro attribute will not recognize the `serde_as` attribute on the field and will not perform the necessary translation steps. -The problem can be avoided by forcing Rust to to evaluate all cfg-expressions before running `serde_as`. +The problem can be avoided by forcing Rust to evaluate all cfg-expressions before running `serde_as`. This is possible with the `#[cfg_eval]` attribute, which is considered for stabilization ([rust#82679], [rust#87221]). As a workaround, it is possible to remove the `serde_as` proc-macro attribute and perform the transformation manually. @@ -124,14 +124,14 @@ map: HashMap<(i32,i32), i32>, ## Implementing `SerializeAs` / `DeserializeAs` You can support [`SerializeAs`] / [`DeserializeAs`] on your own types too. -Most "leaf" types do not need to implement these traits since they are supported implicitly. +Most "leaf" types do not need to implement these traits, since they are supported implicitly. "Leaf" type refers to types which directly serialize like plain data types. -[`SerializeAs`] / [`DeserializeAs`] is very important for collection types, like `Vec` or `BTreeMap`, since they need special handling for they key/value de/serialization such that the conversions can be done on the key/values. +[`SerializeAs`] / [`DeserializeAs`] is very important for collection types, like `Vec` or `BTreeMap`, since they need special handling for the key/value de/serialization such that the conversions can be done on the key/values. You also find them implemented on the conversion types, such as the [`DisplayFromStr`] type. These make up the bulk of this crate and allow you to perform all the nice conversions to [hex strings], the [bytes to string converter], or [duration to UNIX epoch]. -In many cases conversion is only required from one serializable type to another one, without requiring the full power of the `Serialize` or `Deserialize` traits. -In these cases the [`serde_conv!`] macro conveniently allows to define conversion types without the boilerplate. +In many cases, conversion is only required from one serializable type to another one, without requiring the full power of the `Serialize` or `Deserialize` traits. +In these cases, the [`serde_conv!`] macro conveniently allows defining conversion types without the boilerplate. The documentation of [`serde_conv!`] contains more details how to use it. The trait documentations for [`SerializeAs`] and [`DeserializeAs`] describe in details how to implement them for container types like `Box` or `Vec` and other types. @@ -145,7 +145,7 @@ We assume we have a module containing a `serialize` and a `deserialize` function You find an example in the [official serde documentation](https://serde.rs/custom-date-format.html). Our goal is to serialize this `Data` struct. -Right now we do not have anything we can use to replace `???` with, since `_` only works if `RemoteType` would implement `Serialize`, which it does not. +Right now, we do not have anything we can use to replace `???` with, since `_` only works if `RemoteType` would implement `Serialize`, which it does not. ```rust # #[cfg(FALSE)] { @@ -188,7 +188,7 @@ impl<'de> DeserializeAs<'de, RemoteType> for LocalType { This is how the final implementation looks like. We assumed we have a module `MODULE` with a `serialize` function already, which we use here to provide the implementation. -As can be seen this is mostly boilerplate, since the most part is encapsulated in `$module::serialize`. +As can be seen, this is mostly boilerplate, since the most part is encapsulated in `$module::serialize`. The final `Data` struct will now look like: ```rust @@ -205,7 +205,7 @@ struct Data { ### Using `#[serde_as]` with serde's remote derives A special case of the above section is using it on remote derives. -This is a special functionality of serde where it derives the de/serialization code for a type from another crate if all fields are `pub`. +This is a special functionality of serde, where it derives the de/serialization code for a type from another crate if all fields are `pub`. You can find all the details in the [official serde documentation](https://serde.rs/remote-derive.html). ```rust @@ -236,7 +236,7 @@ struct DurationDef { # } ``` -Our goal is it now to use `Duration` within `serde_as`. +Our goal is now to use `Duration` within `serde_as`. We use the existing `DurationDef` type and its `serialize` and `deserialize` functions. We can write this implementation. The implementation for `DeserializeAs` works analogue. diff --git a/serde_with/src/lib.rs b/serde_with/src/lib.rs index 16f96fcf..b09f7577 100644 --- a/serde_with/src/lib.rs +++ b/serde_with/src/lib.rs @@ -58,7 +58,7 @@ //! **Check out the [user guide][user guide] to find out more tips and tricks about this crate.** //! //! For further help using this crate you can [open a new discussion](https://github.com/jonasbb/serde_with/discussions/new) or ask on [users.rust-lang.org](https://users.rust-lang.org/). -//! For bugs please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on Github. +//! For bugs, please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on GitHub. //! //! # Use `serde_with` in your Project //! @@ -113,7 +113,7 @@ //! ## Large and const-generic arrays //! //! serde does not support arrays with more than 32 elements or using const-generics. -//! The `serde_as` attribute allows to circumvent this restriction, even for nested types and nested arrays. +//! The `serde_as` attribute allows circumventing this restriction, even for nested types and nested arrays. //! //! ```rust //! # #[cfg(FALSE)] { @@ -603,7 +603,7 @@ pub struct NoneAsEmptyString; /// ``` /// /// `DefaultOnError` can be combined with other conversion methods. -/// In this example we deserialize a `Vec`, each element is deserialized from a string. +/// In this example, we deserialize a `Vec`, each element is deserialized from a string. /// If the string does not parse as a number, then we get the default value of 0. /// /// ```rust @@ -661,7 +661,7 @@ pub struct DefaultOnError(PhantomData); /// ``` /// /// `DefaultOnNull` can be combined with other conversion methods. -/// In this example we deserialize a `Vec`, each element is deserialized from a string. +/// In this example, we deserialize a `Vec`, each element is deserialized from a string. /// If we encounter null, then we get the default value of 0. /// /// ```rust @@ -783,7 +783,7 @@ pub struct BytesOrString; /// d_f64: Duration::new(12345, 500_000_000), /// d_string: Duration::new(12345, 999_999_999), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "d_u64": 12345, /// "d_f64": 12346.0, @@ -841,7 +841,7 @@ pub struct BytesOrString; /// d_f64: Duration::seconds(-12345) + Duration::milliseconds(500), /// d_string: Duration::seconds(12345) + Duration::nanoseconds(999_999_999), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "d_i64": -12345, /// "d_f64": -12345.0, @@ -920,7 +920,7 @@ pub struct DurationSeconds< /// d_f64: Duration::new(12345, 500_000_000), // Create from seconds and nanoseconds /// d_string: Duration::new(12345, 999_999_000), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "d_f64": 12345.5, /// "d_string": "12345.999999", @@ -971,7 +971,7 @@ pub struct DurationSeconds< /// d_f64: Duration::seconds(-12345) + Duration::milliseconds(500), /// d_string: Duration::seconds(12345) + Duration::nanoseconds(999_999_000), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "d_f64": -12344.5, /// "d_string": "12345.999999", @@ -1105,7 +1105,7 @@ pub struct DurationNanoSecondsWithFrac< /// st_f64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 500_000_000)).unwrap(), /// st_string: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 999_999_999)).unwrap(), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "st_i64": 12345, /// "st_f64": 12346.0, @@ -1163,7 +1163,7 @@ pub struct DurationNanoSecondsWithFrac< /// dt_f64: Local.timestamp(-12345, 500_000_000), /// dt_string: Utc.timestamp(12345, 999_999_999), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "dt_i64": -12345, /// "dt_f64": -12345.0, @@ -1247,7 +1247,7 @@ pub struct TimestampSeconds< /// st_f64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 500_000_000)).unwrap(), /// st_string: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 999_999_000)).unwrap(), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "st_f64": 12345.5, /// "st_string": "12345.999999", @@ -1298,7 +1298,7 @@ pub struct TimestampSeconds< /// dt_f64: Utc.timestamp(-12345, 500_000_000), /// dt_string: Local.timestamp(12345, 999_999_000), /// }; -/// // Observe the different datatypes +/// // Observe the different data types /// let expected = json!({ /// "dt_f64": -12344.5, /// "dt_string": "12345.999999", @@ -1557,7 +1557,7 @@ pub struct Bytes; /// /// Sometimes it is desirable to have a shortcut in writing 1-element lists in a config file. /// Usually, this is done by either writing a list or the list element itself. -/// This distinction is not semantically important on the Rust side, thus both forms should serialize into the same `Vec`. +/// This distinction is not semantically important on the Rust side, thus both forms should deserialize into the same `Vec`. /// /// The `OneOrMany` adapter achieves exactly this use case. /// The serialization behavior can be tweaked to either always serialize as a list using `PreferMany` or to serialize as the inner element if possible using `PreferOne`. diff --git a/serde_with/src/serde_conv.rs b/serde_with/src/serde_conv.rs index 92cce72b..c5659ebf 100644 --- a/serde_with/src/serde_conv.rs +++ b/serde_with/src/serde_conv.rs @@ -1,14 +1,14 @@ /// Create new conversion adapters from functions /// /// The macro lets you create a new converter, which is usable for serde's with-attribute and `#[serde_as]`. -/// Its main use case is to write simple converters for types which are not serializable. +/// Its main use case is to write simple converters for types, which are not serializable. /// Another use-case is to change the serialization behavior if the implemented `Serialize`/`Deserialize` trait is insufficient. /// /// The macro takes four arguments: /// /// 1. The name of the converter type. /// The type can be prefixed with a visibility modifies like `pub` or `pub(crate)`. -/// By default the type is not marked as public (`pub(self)`). +/// By default, the type is not marked as public (`pub(self)`). /// 2. The type `T` we want to extend with custom behavior. /// 3. A function or macro taking a `&T` and returning a serializable type. /// 4. A function or macro taking a deserializable type and returning a `Result`. @@ -16,7 +16,7 @@ /// /// # Example /// -/// In this example we write custom serialization behavior for a `Rgb` type. +/// In this example, we write custom serialization behavior for a `Rgb` type. /// We want to serialize it as a `[u8; 3]`. /// /// ```rust diff --git a/serde_with/src/with_prefix.rs b/serde_with/src/with_prefix.rs index 4d0da4d0..92ae8a33 100644 --- a/serde_with/src/with_prefix.rs +++ b/serde_with/src/with_prefix.rs @@ -34,7 +34,7 @@ use std::fmt; /// } /// ``` /// -/// In Rust we would ideally like to model this data as a pair of `Player` +/// In Rust, we would ideally like to model this data as a pair of `Player` /// structs, rather than repeating the fields of `Player` for each prefix. /// /// ```rust diff --git a/serde_with_macros/src/lib.rs b/serde_with_macros/src/lib.rs index 1cd9422f..229e4617 100644 --- a/serde_with_macros/src/lib.rs +++ b/serde_with_macros/src/lib.rs @@ -245,7 +245,7 @@ where /// /// Existing `skip_serializing_if` annotations will not be altered. /// -/// If some values should always be serialized, then the `serialize_always` can be used. +/// If some values should always be serialized, then `serialize_always` can be used. /// /// # Limitations /// @@ -269,7 +269,7 @@ where /// ``` /// /// Likewise, if you import a type and name it `Option`, the `skip_serializing_if` attributes will be added and compile errors will occur, if `Option::is_none` is not a valid function. -/// Here the function `Vec::is_none` does not exist and therefore the example fails to compile. +/// Here the function `Vec::is_none` does not exist, and therefore the example fails to compile. /// /// ```rust,compile_fail /// # use serde::Serialize; @@ -436,7 +436,7 @@ fn field_has_attribute(field: &Field, namespace: &str, name: &str) -> bool { /// # What this macro does /// /// The `serde_as` macro only serves a convenience function. -/// All the steps it performs, can easily be done manually, in case the cost of an attribute macro is deemed to high. +/// All the steps it performs, can easily be done manually, in case the cost of an attribute macro is deemed too high. /// The functionality can best be described with an example. /// /// ```rust,ignore @@ -449,13 +449,13 @@ fn field_has_attribute(field: &Field, namespace: &str, name: &str) -> bool { /// ``` /// /// 1. All the placeholder type `_` will be replaced with `::serde_with::Same`. -/// The placeholder type `_` marks all the places where the types `Serialize` implementation should be used. +/// The placeholder type `_` marks all the places where the type's `Serialize` implementation should be used. /// In the example, it means that the `u32` values will serialize with the `Serialize` implementation of `u32`. /// The `Same` type implements `SerializeAs` whenever the underlying type implements `Serialize` and is used to make the two traits compatible. /// /// If you specify a custom path for `serde_with` via the `crate` attribute, the path to the `Same` type will be altered accordingly. /// 2. Wrap the type from the annotation inside a `::serde_with::As`. -/// In the above example we know have something like `::serde_with::As::>`. +/// In the above example we now have something like `::serde_with::As::>`. /// The `As` type acts as the opposite of the `Same` type. /// It allows using a `SerializeAs` type whenever a `Serialize` is required. /// 3. Translate the `*as` attributes into the serde equivalent ones. @@ -787,7 +787,7 @@ fn has_type_embedded(type_: &Type, embedded_type: &syn::Ident) -> bool { /// Deserialize value by using its [`FromStr`] implementation /// -/// This is an alternative way to implement `Deserialize` for types which also implement [`FromStr`] by deserializing the type from string. +/// This is an alternative way to implement `Deserialize` for types, which also implement [`FromStr`] by deserializing the type from string. /// Ensure that the struct/enum also implements [`FromStr`]. /// If the implementation is missing, you will get an error message like /// ```text @@ -914,7 +914,7 @@ fn deserialize_fromstr(mut input: DeriveInput, serde_with_crate_path: Path) -> T /// Serialize value by using it's [`Display`] implementation /// -/// This is an alternative way to implement `Serialize` for types which also implement [`Display`] by serializing the type as string. +/// This is an alternative way to implement `Serialize` for types, which also implement [`Display`] by serializing the type as string. /// Ensure that the struct/enum also implements [`Display`]. /// If the implementation is missing, you will get an error message like /// ```text @@ -1003,7 +1003,7 @@ fn serialize_display(mut input: DeriveInput, serde_with_crate_path: Path) -> Tok /// The intend is that keeping the field attributes allows downstream crates to consume and act on them without causing an ordering dependency to the serde_as macro. /// Otherwise, downstream proc-macros would need to be placed *in front of* the main `#[serde_as]` attribute, since otherwise the field attributes would already be stripped off. /// -/// More details about the use-cases in the Github discussion: . +/// More details about the use-cases in the GitHub discussion: . #[proc_macro_derive(__private_consume_serde_as_attributes, attributes(serde_as))] pub fn __private_consume_serde_as_attributes(_: TokenStream) -> TokenStream { TokenStream::new() diff --git a/serde_with_macros/src/utils.rs b/serde_with_macros/src/utils.rs index d7a380af..2d5ab79d 100644 --- a/serde_with_macros/src/utils.rs +++ b/serde_with_macros/src/utils.rs @@ -49,7 +49,7 @@ impl DeriveOptions { } // Inspired by https://github.com/serde-rs/serde/blob/fb2fe409c8f7ad6c95e3096e5e9ede865c8cfb49/serde_derive/src/de.rs#L3120 -// Serde is also licences Apache 2 + MIT +// Serde is also licensed Apache 2 + MIT pub(crate) fn split_with_de_lifetime( generics: &Generics, ) -> (