NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #334 most downloaded on crates.io
proc-macro library for serde_with
Last release 11 days ago
26 Sep 2026
Release timing varies
gaps range from 2 weeks to 3 months
Nearly every release is documented
notes for 53 of 54 stable releases
Nothing withdrawn
no release was ever pulled
8 years old
58 releases · first in 2019
Implement JsonSchemaAs for NoneAsEmptyString , so fields using it compile with the schemars_* features
JsonSchemaAs for NoneAsEmptyString, so fields using it compile with the schemars_* features (#1014)with_prefix! and with_suffix! available with the alloc feature, instead of only with std (#1008)Update syn and darling dependencies to use syn v3
One column per quarter.
syn and darling dependencies to use syn v3 (#992)base64 to a newer version. This should not have any API change, but some error messages might change. (#993)serde_as can now parse cfg_attr(true, ...) and cfg_attr(false, ...) (#995)true/false are new literals as of Rust 1.88 but need to be parsed explicitly with the syn types.schemars annotations.Add support for jiff v0.2 behind the new jiff_0_2 feature flag ( #936 ) jiff::SignedDuration works with DurationSeconds and its variants. jiff::Timest
jiff v0.2 behind the new jiff_0_2 feature flag (#936)jiff::SignedDuration works with DurationSeconds and its variants.jiff::Timestamp, jiff::Zoned, and jiff::civil::DateTime work with TimestampSeconds and its variants.jiff::Zoned uses the system time zone, like chrono::DateTime<Local>.rust::sets_duplicate_value_is_error, rust::maps_duplicate_key_is_error, rust::sets_last_value_wins, and rust::maps_first_key_wins adapters created their backing sets/maps with with_capacity_and_hasher using the raw deserializer size_hint, bypassing the size_hint_cautious cap added in #966 (the clippy.toml disallowed_methods lint only covers Vec::with_capacity, not with_capacity_and_hasher, so these sites were not flagged).Hash table capacity overflow before a single element was read. All such constructions now route through size_hint_cautious.GHSA-7gcf-g7xr-8hxj : KeyValueMap serialization panics on empty sequence or map entries Bad or attacker controlled values could cause a panic while al
GHSA-7gcf-g7xr-8hxj: KeyValueMap serialization panics on empty sequence or map entries
Bad or attacker controlled values could cause a panic while allocating too large values.
Fixed in #966 by setting a maximum allocation size during the creation of collections like Vec or sets.
Thanks to @7thParkk for reporting the issue.
NoneAsZero adapter that maps Option<NonZero*> to a plain integer, encoding None as 0 by @SAY-5 (#486)Add support for base58 encoding, similar to the existing base64 setup by @mitinarseny
base58 encoding, similar to the existing base64 setup by @mitinarseny (#943)base64 with schemars support by @mitinarseny (#9949)Add support for hashbrown v0.17
Add support for hashbrown v0.17 (#940)
This extends the existing support for hashbrown to the newly released version.
Support OneOrMany with more sequence and set types
OneOrMany with more sequence and set types (#929)darling dependencySupport OneOrMany with smallvec v1 ( #920 , #922 )
SerializeDisplayAlt.
Remove unsupported attributes from example.Fix JsonSchemaAs of SetPreventDuplicates and SetLastValueWins . ( #906 , #907 )
Added support for smallvec v1 under the smallvec_1 feature flag by @isharma228
smallvec v1 under the smallvec_1 feature flag by @isharma228 (#895)JsonSchemaAs implementation for json::JsonString by @yogevm15 (#901)Fix building of the documentation by updating references to use serde_core .
serde_core.Added error inspection to VecSkipError and MapSkipError by @michelhe ( #878 ) This allows interacting with the previously hidden error, for example fo
Added error inspection to VecSkipError and MapSkipError by @michelhe (#878)
This allows interacting with the previously hidden error, for example for logging.
Checkout the newly added example to both types.
Allow documenting the types generated by serde_conv!.
The serde_conv! macro now acceps outer attributes before the optional visibility modifier.
This allow adding doc comments in the shape of #[doc = "..."] or any other attributes, such as lint modifiers.
serde_conv!(
#[doc = "Serialize bools as string"]
#[allow(dead_code)]
pub BoolAsString,
bool,
|x: &bool| ::std::string::ToString::to_string(x),
|x: ::std::string::String| x.parse()
);Add support for hashbrown v0.16 (#877)
This extends the existing support for hashbrown v0.14 and v0.15 to the newly released version.
toml dev-dependency.Show macro expansion in the docs.rs generated rustdoc. Since macros are used to generate trait implementations, this is useful to understand the exact
Added support for schemars v1 under the schemars_1 feature flag
schemars v1 under the schemars_1 feature flagIntroduce SerializeDisplayAlt derive macro (#833) An alternative to the SerializeDisplay macro except instead of using the plain formatting like forma
SerializeDisplayAlt derive macro (#833)
An alternative to the SerializeDisplay macro except instead of using the
plain formatting like format!("{}", ...), it serializes with the
Formatter::alternate flag set to true, like format!("{:#}", ...)No changes.
No changes.
No changes.
No changes.
Proper handling of cfg_attr in the serde_as macro by @sivizius
Proper handling of cfg_attr in the serde_as macro by @sivizius (#782)
This allows to parse more valid forms of the cfg_attr macro, including multiple values and attribute that do not follow the key = value schema.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
Detect conflicting schema_with attributes on fields with schemars annotations by @swlynch99 (#715) This extends the existing avoidance mechanism to a
schema_with attributes on fields with schemars annotations by @swlynch99 (#715)
This extends the existing avoidance mechanism to a new variant fixing #712.No changes.
No changes.
No changes.
No changes.
The serde_as macro now better detects existing schemars attributes on fields and incorporates them (#682) This avoids errors on existing #[schemars(wi
serde_as macro now better detects existing schemars attributes on fields and incorporates them (#682)
This avoids errors on existing #[schemars(with = ...)] annotations.Support for schemars integration added by @swlynch99 (#666) The serde_as macro can now detect schemars usage and emits matching annotations for all fi
schemars integration added by @swlynch99 (#666)
The serde_as macro can now detect schemars usage and emits matching annotations for all fields with serde_as attribute.No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
Update syn to v2 and darling to v0.20 (#578) Update proc-macro dependencies. This change should have no impact on users, but now uses the same depende
syn to v2 and darling to v0.20 (#578)
Update proc-macro dependencies.
This change should have no impact on users, but now uses the same dependency as serde_derive.No changes.
No changes.
No changes.
No changes.
No changes.
No changes.
serde_with::apply had an issue matching types when invisible token groups where in use (#538) The token groups can stem from macro_rules expansion, bu
serde_with::apply had an issue matching types when invisible token groups where in use (#538)
The token groups can stem from macro_rules expansion, but should be treated mostly transparent.
The old code required a group to match a group, while now groups are silently removed when checking for type patterns.Add new apply attribute to simplify repetitive attributes over many fields. Multiple rules and multiple attributes can be provided each.
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 attributes 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>.
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.
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, su
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).…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…
No changes compared to v2.0.0-rc.0.
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.
Optionstd::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_as] and #[skip_serializing_none] attributes must always be placed before #[derive].…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…
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.
Optionstd::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_as] and #[skip_serializing_none] attributes must always be placed before #[derive].Account for generics when deriving implementations with SerializeDisplay and DeserializeFromStr #413
SerializeDisplay and DeserializeFromStr #413The minimal supported Rust version (MSRV) is now specified in the Cargo.toml via the rust-version field. The field is supported in Rust 1.56 and has n
The minimal supported Rust version (MSRV) is now specified in the Cargo.toml via the rust-version field. The field is supported in Rust 1.56 and has no effect on versions before.
More details: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
Add the attribute #[serde(borrow)] on a field if serde_as is used in combination with the BorrowCow type.
#[serde(borrow)] on a field if serde_as is used in combination with the BorrowCow type.Describe how the serde_as macro works on a high level.
serde_as macro works on a high level.SerializeDisplay and DeserializeFromStr were relying on the prelude where they were used.
Properly name all types and traits required for the expanded code to work.
The tests were improved to be better able to catch such problems.Nothing published for this version
Improve error messages when #[serde_as(..)] is misused as a field attribute. Thanks to @Lehona for reporting the bug in #233.
Improve error messages when #[serde_as(..)] is misused as a field attribute.
Thanks to @Lehona for reporting the bug in #233.
Internal cleanup for assembling and parsing attributes during serde_as processing.
Change processing on #[serde_as(...)] attributes on fields.
The attributes will no longer be stripped during proc-macro processing. Instead, a private derive macro is applied to the struct/enum which captures them and makes them inert, thus allowing compilation.
This should have no effect on the generated code and on the runtime behavior.
It eases integration of third-party crates with serde_with, since they can now process the #[serde_as(...)] field attributes reliably.
Before this, it was impossible for derive macros and lead to awkward ordering constraints on the attribute macros.
Thanks to @Lehona for reporting this problem and to @dtolnay for suggesting the dummy derive macro.
Support specifying a path to the serde_with crate for the serde_as and derive macros. This is useful when using crate renaming in Cargo.toml or while
Support specifying a path to the serde_with crate for the serde_as and derive macros.
This is useful when using crate renaming in Cargo.toml or while re-exporting the macros.
Many thanks to @tobz1000 for raising the issue and contributing fixes.
@adwhit contributed an improvement to DeserializeFromStr which allows it to deserialize from bytes (#186). This makes the derived implementation appli
DeserializeFromStr which allows it to deserialize from bytes (#186).
This makes the derived implementation applicable in more situations.The derive macros SerializeDisplay and DeserializeFromStr now use the properly namespaced types and traits. This solves conflicts with Result if Resul
The derive macros SerializeDisplay and DeserializeFromStr now use the properly namespaced types and traits.
This solves conflicts with Result if Result is not std::result::Result, e.g., a type alias.
Additionally, the code assumed that FromStr was in scope, which is now also not required.
Thanks to @adwhit for reporting and fixing the problem in #186.
Add serde_as macro. Refer to the serde_with crate for details.
serde_as macro. Refer to the serde_with crate for details.SerializeDisplay and DeserializeFromStr, which implement the Serialize/Deserialize traits based on Display and FromStr.
This is in addition to the pre-existing methods like DisplayFromStr, which act locally, whereas the derive macros provide the traits expected by the rest of the ecosystem.serde_as macro now supports serde attributes and no longer panic on unrecognized values in the attribute.Add two derive macros, SerializeDisplay and DeserializeFromStr, which implement the Serialize/Deserialize traits based on Display and FromStr. This is
SerializeDisplay and DeserializeFromStr, which implement the Serialize/Deserialize traits based on Display and FromStr.
This is in addition to the pre-existing methods like DisplayFromStr, which act locally, whereas the derive macros provide the traits expected by the rest of the ecosystem.The serde_as macro now supports serde attributes and no longer panic on unrecognized values in the attribute.
serde_as macro now supports serde attributes and no longer panic on unrecognized values in the attribute.Add serde_as macro. Refer to the serde_with crate for details.
serde_as macro. Refer to the serde_with crate for details.Bump minimal Rust version to 1.36.0 to support Rust Edition 2018
cargo audit and tarpaulin in all configurations now.Features for the syn dependency were missing. This was hidden due to the dev-dependencies whose features leaked into the normal build.
syn dependency were missing.
This was hidden due to the dev-dependencies whose features leaked into the normal build.Add skip_serializing_none attribute, which adds #[serde(skip_serializing_if = "Option::is_none")] for each Option in a struct. This is helpful for API
Initial Release
skip_serializing_none attribute, which adds #[serde(skip_serializing_if = "Option::is_none")] for each Option in a struct.
This is helpful for APIs which have many optional fields.
The effect of can be negated by adding serialize_always on those fields, which should always be serialized.
Existing skip_serializing_if will never be modified and those fields keep their behavior.Your coding agent can read these notes before it upgrades. Set up the MCP server →