Skip to content

Releases: jonasbb/serde_with

serde_with v2.1.0

16 Nov 22:23
8aaacb6
Compare
Choose a tag to compare

Added

  • Add new apply attribute to simplify repetitive attributes over many fields.
    Multiple rules and multiple attributes can be provided each.

    #[serde_with::apply(
        Option => #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")],
        Option<bool> => #[serde(rename = "bool")],
    )]
    #[derive(serde::Serialize)]
    struct Data {
        a: Option<String>,
        b: Option<u64>,
        c: Option<String>,
        d: Option<bool>,
    }

    The apply attribute will expand into this, applying the attributs to the matching fields:

    #[derive(serde::Serialize)]
    struct Data {
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        a: Option<String>,
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        b: Option<u64>,
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        c: Option<String>,
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        #[serde(rename = "bool")]
        d: Option<bool>,
    }

    The attribute supports field matching using many rules, such as _ to apply to all fields and partial generics like Option to match any Option be it Option<String>, Option<bool>, or Option<T>.

Fixed

  • The derive macros SerializeDisplay and DeserializeFromStr now take better care not to use conflicting names for generic values. (#526)
    All used generics now start with __ to make conflicts with manually written code unlikely.

    Thanks to @Elrendio for submitting a PR fixing the issue.

serde_with_macros v2.1.0

16 Nov 22:19
8aaacb6
Compare
Choose a tag to compare

Added

  • Add new apply attribute to simplify repetitive attributes over many fields.
    Multiple rules and multiple attributes can be provided each.

    #[serde_with::apply(
        Option => #[serde(default)] #[serde(skip_serializing_if = "Option::is_none")],
        Option<bool> => #[serde(rename = "bool")],
    )]
    #[derive(serde::Serialize)]
    struct Data {
        a: Option<String>,
        b: Option<u64>,
        c: Option<String>,
        d: Option<bool>,
    }

    The apply attribute will expand into this, applying the attributs to the matching fields:

    #[derive(serde::Serialize)]
    struct Data {
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        a: Option<String>,
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        b: Option<u64>,
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        c: Option<String>,
        #[serde(default)]
        #[serde(skip_serializing_if = "Option::is_none")]
        #[serde(rename = "bool")]
        d: Option<bool>,
    }

    The attribute supports field matching using many rules, such as _ to apply to all fields and partial generics like Option to match any Option be it Option<String>, Option<bool>, or Option<T>.

Fixed

  • The derive macros SerializeDisplay and DeserializeFromStr now take better care not to use conflicting names for generic values. (#526)
    All used generics now start with __ to make conflicts with manually written code unlikely.

    Thanks to @Elrendio for submitting a PR fixing the issue.

serde_with v2.0.1

09 Sep 20:43
v2.0.1
7753240
Compare
Choose a tag to compare

Added

  • time added support for the well-known Iso8601 format.
    This extends the existing support of Rfc2822 and Rfc3339.

Changed

  • Warn if serde_as is used on an enum variant.
    Attributes on enum variants were never supported.
    But #[serde(with = "...")] can be added on variants, such that some confusion can occur when migration (#499).

Note

A cargo bug (cargo#10801) means that upgrading from v1 to v2 may add unnecessary crates to the Cargo.lock file.
A diff of the lock-file makes it seem that serde_with depends on new crates, even though these crates are unused and will not get compiled or linked.
However, tools consuming Cargo.lock or cargo metadata might give wrong results.

serde_with_macros v2.0.1

09 Sep 20:41
macros-v2.0.1
7753240
Compare
Choose a tag to compare

Changed

  • Warn if serde_as is used on an enum variant.
    Attributes on enum variants were never supported.
    But #[serde(with = "...")] can be added on variants, such that some confusion can occur when migration (#499).

serde_with v2.0.0

17 Jul 21:37
v2.0.0
625e59a
Compare
Choose a tag to compare

Added

  • Make JsonString<T> smarter by allowing nesting serde_as definitions.
    This allows applying custom serialization logic, before the value gets converted into a JSON string.

    // Rust
    #[serde_as(as = "JsonString<Vec<(JsonString, _)>>")]
    value: BTreeMap<[u8; 2], u32>,
    
    // JSON
    {"value":"[[\"[1,2]\",3],[\"[4,5]\",6]]"}

Changed

  • Make #[serde_as] behave more intuitive on Option<T> fields.

    The #[serde_as] macro now detects if a #[serde_as(as = "Option<S>")] is used on a field of type Option<T> and applies #[serde(default)] to the field.
    This restores the ability to deserialize with missing fields and fixes a common annoyance (#183, #185, #311, #417).
    This is a breaking change, since now deserialization will pass where it did not before and this might be undesired.

    The Option field and transformation are detected by directly matching on the type name.
    These variants are detected as Option.

    • Option
    • std::option::Option, with or without leading ::
    • core::option::Option, with or without leading ::

    If an existing default attribute is detected, the attribute is not applied again.
    This behavior can be suppressed by using #[serde_as(no_default)] or #[serde_as(as = "Option<S>", no_default)].

  • NoneAsEmptyString and string_empty_as_none use a different serialization bound (#388).

    Both types used AsRef<str> as the serialization bound.
    This is limiting for non-string types like Option<i32>.
    The deserialization often was already more flexible, due to the FromStr bound.

    For most std types this should have little impact, as the types implementing AsRef<str> mostly implement Display, too, such as String, Cow<str>, or Rc<str>.

  • Bump MSRV to 1.60. This is required for the optional dependency feature syntax in cargo.

Removed

  • Remove old module based conversions.

    The newer serde_as based conversions are preferred.

    • seq_display_fromstr: Use DisplayFromStr in combination with your container type:

      #[serde_as(as = "BTreeSet<DisplayFromStr>")]
      addresses: BTreeSet<Ipv4Addr>,
      #[serde_as(as = "Vec<DisplayFromStr>")]
      bools: Vec<bool>,
    • tuple_list_as_map: Use BTreeMap on a Vec of tuples:

      #[serde_as(as = "BTreeMap<_, _>")] // HashMap will also work
      s: Vec<(i32, String)>,
    • map_as_tuple_list can be replaced with #[serde_as(as = "Vec<(_, _)>")].

    • display_fromstr can be replaced with #[serde_as(as = "DisplayFromStr")].

    • bytes_or_string can be replaced with #[serde_as(as = "BytesOrString")].

    • default_on_error can be replaced with #[serde_as(as = "DefaultOnError")].

    • default_on_null can be replaced with #[serde_as(as = "DefaultOnNull")].

    • string_empty_as_none can be replaced with #[serde_as(as = "NoneAsEmptyString")].

    • StringWithSeparator can now only be used in serde_as.
      The definition of the Separator trait and its implementations have been moved to the formats module.

    • json::nested can be replaced with #[serde_as(as = "json::JsonString")].

  • Remove previously deprecated modules.

    • sets_first_value_wins
    • btreemap_as_tuple_list and hashmap_as_tuple_list can be replaced with #[serde_as(as = "Vec<(_, _)>")].

serde_with_macros v2.0.0

17 Jul 21:35
macros-v2.0.0
625e59a
Compare
Choose a tag to compare

No changes compared to v2.0.0-rc.0.

Changed

  • Make #[serde_as] behave more intuitive on Option<T> fields.

    The #[serde_as] macro now detects if a #[serde_as(as = "Option<S>")] is used on a field of type Option<T> and applies #[serde(default)] to the field.
    This restores the ability to deserialize with missing fields and fixes a common annoyance (#183, #185, #311, #417).
    This is a breaking change, since now deserialization will pass where it did not before and this might be undesired.

    The Option field and transformation are detected by directly matching on the type name.
    These variants are detected as Option.

    • Option
    • std::option::Option, with or without leading ::
    • core::option::Option, with or without leading ::

    If an existing default attribute is detected, the attribute is not applied again.
    This behavior can be supressed by using #[serde_as(no_default)] or #[serde_as(as = "Option<S>", no_default)].

Fixed

  • Make the documentation clearer by stating that the #[serde_as] and #[skip_serializing_none] attributes must always be placed before #[derive].

serde_with v2.0.0-rc.0

29 Jun 21:25
v2.0.0-rc.0
6969abf
Compare
Choose a tag to compare
Pre-release

Changed

  • Make #[serde_as] behave more intuitive on Option<T> fields.

    The #[serde_as] macro now detects if a #[serde_as(as = "Option<S>")] is used on a field of type Option<T> and applies #[serde(default)] to the field.
    This restores the ability to deserialize with missing fields and fixes a common annoyance (#183, #185, #311, #417).
    This is a breaking change, since now deserialization will pass where it did not before and this might be undesired.

    The Option field and transformation are detected by directly matching on the type name.
    These variants are detected as Option.

    • Option
    • std::option::Option, with or without leading ::
    • core::option::Option, with or without leading ::

    If an existing default attribute is detected, the attribute is not applied again.
    This behavior can be suppressed by using #[serde_as(no_default)] or #[serde_as(as = "Option<S>", no_default)].

  • NoneAsEmptyString and string_empty_as_none use a different serialization bound (#388).

    Both types used AsRef<str> as the serialization bound.
    This is limiting for non-string types like Option<i32>.
    The deserialization often was already more flexible, due to the FromStr bound.

    For most std types this should have little impact, as the types implementing AsRef<str> mostly implement Display, too, such as String, Cow<str>, or Rc<str>.

  • Bump MSRV to 1.60. This is required for the optional dependency feature syntax in cargo.

Removed

  • Remove old module based conversions.

    The newer serde_as based conversions are preferred.

    • seq_display_fromstr: Use DisplayFromStr in combination with your container type:

      #[serde_as(as = "BTreeSet<DisplayFromStr>")]
      addresses: BTreeSet<Ipv4Addr>,
      #[serde_as(as = "Vec<DisplayFromStr>")]
      bools: Vec<bool>,
    • tuple_list_as_map: Use BTreeMap on a Vec of tuples:

      #[serde_as(as = "BTreeMap<_, _>")] // HashMap will also work
      s: Vec<(i32, String)>,
    • map_as_tuple_list can be replaced with #[serde_as(as = "Vec<(_, _)>")].

    • display_fromstr can be replaced with #[serde_as(as = "DisplayFromStr")].

    • bytes_or_string can be replaced with #[serde_as(as = "BytesOrString")].

    • default_on_error can be replaced with #[serde_as(as = "DefaultOnError")].

    • default_on_null can be replaced with #[serde_as(as = "DefaultOnNull")].

    • string_empty_as_none can be replaced with #[serde_as(as = "NoneAsEmptyString")].

    • StringWithSeparator can now only be used in serde_as.
      The definition of the Separator trait and its implementations have been moved to the formats module.

    • json::nested can be replaced with #[serde_as(as = "json::JsonString")].

  • Remove previously deprecated modules.

    • sets_first_value_wins
    • btreemap_as_tuple_list and hashmap_as_tuple_list can be replaced with #[serde_as(as = "Vec<(_, _)>")].

serde_with_macros v2.0.0-rc.0

29 Jun 21:22
macros-v2.0.0-rc.0
6969abf
Compare
Choose a tag to compare
Pre-release

Changed

  • Make #[serde_as] behave more intuitive on Option<T> fields.

    The #[serde_as] macro now detects if a #[serde_as(as = "Option<S>")] is used on a field of type Option<T> and applies #[serde(default)] to the field.
    This restores the ability to deserialize with missing fields and fixes a common annoyance (#183, #185, #311, #417).
    This is a breaking change, since now deserialization will pass where it did not before and this might be undesired.

    The Option field and transformation are detected by directly matching on the type name.
    These variants are detected as Option.

    • Option
    • std::option::Option, with or without leading ::
    • core::option::Option, with or without leading ::

    If an existing default attribute is detected, the attribute is not applied again.
    This behavior can be suppressed by using #[serde_as(no_default)] or #[serde_as(as = "Option<S>", no_default)].

serde_with v1.14.0

29 May 16:52
v1.14.0
8c59954
Compare
Choose a tag to compare

Added

  • Add support for time crate v0.3 #450

    time::Duration can now be serialized with the DurationSeconds and related converters.

    // Rust
    #[serde_as(as = "serde_with::DurationSeconds<u64>")]
    value: Duration,
    
    // JSON
    "value": 86400,

    time::OffsetDateTime and time::PrimitiveDateTime can now be serialized with the TimestampSeconds and related converters.

    // Rust
    #[serde_as(as = "serde_with::TimestampMicroSecondsWithFrac<String>")]
    value: time::PrimitiveDateTime,
    
    // JSON
    "value": "1000000",

    time::OffsetDateTime can be serialized in string format in different well-known formats.
    Two formats are supported, time::format_description::well_known::Rfc2822 and time::format_description::well_known::Rfc3339.

    // Rust
    #[serde_as(as = "time::format_description::well_known::Rfc2822")]
    rfc_2822: OffsetDateTime,
    #[serde_as(as = "Vec<time::format_description::well_known::Rfc3339>")]
    rfc_3339: Vec<OffsetDateTime>,
    
    // JSON
    "rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
    "rfc_3339": ["1997-11-21T09:55:06-06:00"],
  • Deserialize bool from integers #456 462

    Deserialize an integer and convert it into a bool.
    BoolFromInt<Strict> (default) deserializes 0 to false and 1 to true, other numbers are errors.
    BoolFromInt<Flexible> deserializes any non-zero as true.
    Serialization only emits 0/1.

    // Rust
    #[serde_as(as = "BoolFromInt")] // BoolFromInt<Strict>
    b: bool,
    
    // JSON
    "b": 1,

Changed

  • Bump MSRV to 1.53, since the new dependency time requires that version.

Fixed

  • Make the documentation clearer by stating that the #[serde_as] and #[skip_serializing_none] attributes must always be places before #[derive].

serde_with v1.13.0

23 Apr 12:07
v1.13.0
6fe1198
Compare
Choose a tag to compare

Added

  • Added support for indexmap::IndexMap and indexmap::IndexSet types. #431, #436

    Both types are now compatible with these functions: maps_duplicate_key_is_error, maps_first_key_wins, sets_duplicate_value_is_error, sets_last_value_wins.
    serde_as integration is provided by implementing both SerializeAs and DeserializeAs for both types.
    IndexMaps can also be serialized as a list of types via the serde_as(as = "Vec<(_, _)>") annotation.

    All implementations are gated behind the indexmap feature.

    Thanks to @jgrund for providing parts of the implementation.