Compare Versions - serde
Crates.io / serde / Compare Versions
- Allow building documentation with
RUSTDOCFLAGS='--cfg=docsrs'set for the whole dependency graph (#2995)
- Documentation improvements (#2991)
- Deduplicate variant matching logic inside generated Deserialize impl for adjacently tagged enums (#2935, thanks @Mingun)
- Avoid triggering a deprecation warning in derived Serialize and Deserialize impls for a data structure that contains its own deprecations (#2879, thanks @rcrisanti)
- Remove private types being suggested in rustc diagnostics (#2979)
- Fix serde_core documentation links (#2978)
- Make
serialize_withattribute produce code that works if respanned to 2024 edition (#2950, thanks @aytey)
- Documentation improvements (#2973)
- Deprecate
serde_if_integer128!macro (#2975)
- Add a way for data formats to depend on serde traits without waiting for serde_derive compilation: https://docs.rs/serde_core (#2608, thanks @osiewicz)
- Prevent
absolute_pathsClippy restriction being triggered inside macro-generated code (#2906, thanks @davidzeng0)
- Documentation improvements
- Support serializing externally tagged unit variant inside flattened field (#2786, thanks @Mingun)
- Mark all generated impls with #[automatically_derived] to exclude from code coverage (#2866, #2868, thanks @tdittr)
- Produce warning when multiple fields or variants have the same deserialization name (#2855, #2856, #2857)
- Implement IntoDeserializer for all Deserializers in serde::de::value module (#2568, thanks @Mingun)
- Fix support for macro-generated
withattributes inside a newtype struct (#2847)
- Fix hygiene of macro-generated local variable accesses in serde(with) wrappers (#2845)
- Improve error reporting about mismatched signature in
withanddefaultattributes (#2558, thanks @Mingun) - Show variant aliases in error message when variant deserialization fails (#2566, thanks @Mingun)
- Improve binary size of untagged enum and internally tagged enum deserialization by about 12% (#2821)
- Support serializing and deserializing
IpAddrandSocketAddrin no-std mode on Rust 1.77+ (#2816, thanks @MathiasKoch) - Make
serde::ser::StdErrorandserde::de::StdErrorequivalent tocore::error::Erroron Rust 1.81+ (#2818)
- Fix deserialization of empty structs and empty tuples inside of untagged enums (#2805, thanks @Mingun)
- Support serializing and deserializing unit structs in a
flattenfield (#2802, thanks @jonhoo)
- Improve interactions between
flattenattribute andskip_serializing/skip_deserializing(#2795, thanks @Mingun)
- Improve support for
flattenattribute inside of enums (#2567, thanks @Mingun)
- Use serialize_entry instead of serialize_key + serialize_value when serialize flattened newtype enum variants (#2785, thanks @Mingun)
- Avoid triggering a collection_is_never_read lint in the deserialization of enums containing flattened fields (#2791)
- Apply #[diagnostic::on_unimplemented] attribute on Rust 1.78+ to suggest adding serde derive or enabling a "serde" feature flag in dependencies (#2767, thanks @weiznich)
- Documentation improvements (#2747)
- Provide public access to RenameAllRules in serde_derive_internals (#2743)
- Resolve unexpected_cfgs warning (#2737)
- Fix formatting of "invalid type" and "invalid value" deserialization error messages containing NaN or infinite floats (#2733, thanks @jamessan)
- Fix ambiguous associated item when
forward_to_deserialize_any!is used on an enum withErrorvariant (#2732, thanks @aatifsyed)
- Support serializing and deserializing
Saturating<T>(#2709, thanks @jbethune)
- Fix unused_imports warnings when compiled by rustc 1.78
- Optimize code size of some Display impls (#2697, thanks @nyurik)
- Improve formatting of "invalid type" error messages involving floats (#2682)
- Prevent remote definitions of tuple struct or tuple variant from triggering dead_code warning (#2671)
- Update proc-macro2 to fix caching issue when using a rustc-wrapper such as sccache
- Fix field names used for the deserialization of
RangeFromandRangeTo(#2653, #2654, #2655, thanks @emilbonnek)
- Allow internal tag field in untagged variant (#2646, thanks @robsdedude)
- Documentation improvements
- Preserve NaN sign when deserializing f32 from f64 or vice versa (#2637)
- Fix "cannot infer type" error when internally tagged enum contains untagged variant (#2613, thanks @ahl)
- Fix "failed to parse manifest" error when building serde using a Cargo version between 1.45 and 1.50 (#2603)
- Remove support for Emscripten targets on rustc older than 1.40 (#2600)
- Disallow incompatible versions of
serde_deriveandserdein the dependency graph (#2588, thanks @soqb)
- Fix error "cannot move out of
*selfwhich is behind a shared reference" deriving Serialize on a non_exhaustive enum (#2591)
- Restore from-source
serde_derivebuild on all platforms — eventually we'd like to use a first-class precompiled macro if such a thing becomes supported by cargo / crates.io
- Support deserializing
Box<OsStr>with an equivalent representation asOsString(#2556, thanks @DBLouis)
- Render field aliases in sorted order in error messages (#2458, thanks @Mingun)
- Support
serde(default)on tuple structs (#2553, thanks @Mingun)
- Make
serde(alias)work in combination withflattenwhen using in-place deserialization (#2443, thanks @Mingun) - Improve the representation of adjacently tagged enums in formats where enum tags are serialized by index, as opposed to by string name (#2505, #2496, thanks @Baptistemontan)
- Update to 2018 edition
- Support serialization of tuple variants inside a flattened field (#2448, thanks @Mingun)
- Fix build error when using serde with "std" feature turned off and "unstable" feature turned on (#2541)
- Add
serde(rename_all_fields = "...")attribute to apply arename_allon every struct variant of an enum (#1695, thanks @jplatte) - Improve diagnostics for attribute parse errors (#2536, thanks @jplatte)
- Allow tag field of an internally tagged enum to have same name as a field inside a skipped struct variant (#2266, thanks @flisky)
- Restore missing LICENSE files in serde_derive crate (#2527, thanks @ankane)
- Documentation improvements
- Fix missing trait implementations when using serde derive macro on a macro-generated data structure, such as via the
bitflagscrate (#2516)
- Experiment with precompiling the serde_derive macros to reduce build time (#2514)
- Support
derive(Deserialize)on unit structs that have const generics (#2500, thanks @Baptistemontan)
- Produce error message on suffixed string literals inside serde attributes (#2242)
- Support single identifier as unbraced default value for const generic parameter (#2449)
- Add Deserializer::deserialize_identifier support for adjacently tagged enums (#2475, thanks @Baptistemontan)
- Fix unused_braces lint in generated Deserialize impl that uses braced const generic expressions (#2414)
- Allow
serde::de::IgnoredAnyto be the type for aserde(flatten)field (#2436, thanks @Mingun) - Allow larger preallocated capacity for smaller elements (#2494)
- Add serialize and deserialize impls for
RangeFromandRangeTo(#2471, thanks @tbu-)
- Add
no-alloccategory to crates.io metadata
- Fix incorrect count of fields passed to tuple deserialization methods when using
serde(skip_deserializing)attributes (#2466, thanks @Mingun) - Fix
-Zminimal-versionsbuild
- Allowed enum variants to be individually marked as untagged (#2403, thanks @dewert99)
- Eliminate build script from serde_derive crate to slightly reduce build time (#2442, thanks @taiki-e)
-
Support deserializing flattened adjacently tagged enums from data formats which represent fields as bytes, such as the
csvcrate (#2377, thanks @mfro)#[derive(Deserialize)] pub struct Record { common: u64, #[serde(flatten)] kind: Kind, } #[derive(Deserialize)] #[serde(tag = "kind", content = "parameter", rename_all = "lowercase")] enum Kind { Foo(u64), Bar(bool), }common,kind,parameter 1,foo,42 2,bar,true
- Improve error messages produced by serde_test on test failure (#2435, thanks @Mingun)
- Make derived serializer/deserializer internals
doc(hidden)(#2426, thanks @compiler-errors)
- Accept empty #[serde()] attribute (#2422)
- Fix "expected serde crate attribute to be a string" error when using macro_rules metavariable inside of serde attribute:
#[serde(crate = $serde_path)](#2409)
- Update syn dependency to 2.x
- Documentation improvements
- Support
SerializeandDeserializeimpls forcore::ffi::CStrandalloc::ffi::CStringwithout "std" feature (#2374, thanks @safarir)
- Fix "undeclared lifetime" error in generated code when deriving Deserialize for an enum with both
flattenand'staticfields (#2383, thanks @Mingun)
- Support
serde(alias = "…")attribute used inside of flattened struct (#2387, thanks @bebecue)
- Documentation improvements
- Update
serde::{ser,de}::StdErrorto re-exportcore::error::Errorwhen serde is built withfeature="std"off andfeature="unstable"on (#2344)
- Relax some trait bounds from the
Serializeimpl ofHashMapandBTreeMap(#2334) - Enable
SerializeandDeserializeimpls ofstd::sync::atomictypes on more platforms (#2337, thanks @badboy)
- Relax some trait bounds from the
Serializeimpl ofBinaryHeap,BTreeSet, andHashSet(#2333, thanks @jonasbb)
- Support
remotederive for generic types that have private fields (#2327)
- Add
serde::de::value::EnumAccessDeserializerwhich transforms anEnumAccessinto aDeserializer(#2305)
- Allow internally tagged newtype variant to contain unit (#2303, thanks @tage64)
- Allow RefCell<T>, Mutex<T>, and RwLock<T> to be serialized regardless of whether T is
Sized(#2282, thanks @ChayimFriedman2)
- Change atomic ordering used by Serialize impl of atomic types to match ordering used by Debug impl of those same types (#2263, thanks @taiki-e)
- Invert build.rs cfgs in serde_test to produce the most modern configuration in the default case (#2253, thanks @taiki-e)
- Add keywords to crates.io metadata
- Add
no-stdcategory to crates.io metadata
- Invert serde_derive cfgs to convenience non-Cargo builds on a modern toolchain (#2251, thanks @taiki-e)
- Add
newconstructor function for allIntoDeserializerimpls (#2246)
- Documentation improvements
- Update documentation links to some data formats whose repos have moved (#2201, thanks @atouchet)
- Fix declared
rust-versionof serde and serde_test (#2168)
- Improve default error message when
Visitorfails to deserialize a u128 or i128 (#2167)
- Update discord channels listed in readme
- Improve error messages on deserializing NonZero integers from a 0 value (#2158)
- Optimize deserialization of data structures that contain recursive use of
flattenfields ortagoruntaggedenums (#2148)
- Enable Serialize and Deserialize impls for
std::sync::atomic::{AtomicI64, AtomicU64}on riscv64 arch (#2141, thanks @Avimitin)
- Avoid
unused_resultsbeing triggered in generated code for adjacently tagged enum (#2116, thanks @tyranron)
- Provide
MapAccessandSeqAccessimpl for reference to a dynamically sized existing impl (#2081)
- Support deserialization of remote structs that used packed repr (#2078, #2079, #2080)
- Enable 128-bit integers on emscripten in Rust 1.40+ (#2076, thanks @Manishearth)
- Resolve warning in rustc nightly-2021-07-31+ compiling serde_test
- Resolve conflict with
forbid(future_incompatible)lint setting in generated code (#2026, thanks @hyd-dev)
- Improve performance of serializing
Ipv4Addr(#2001, thanks @saethlin)
- Fix possible panic deserializing invalid data as
SystemTime(#1997, thanks @cyang1)
- Support
Selfkeywords in fields of types that derive Deserialize (#1830, thanks @taiki-e) - Allow floats to be deserialized from ints in tagged unions (#1842, thanks @Timmmm)
- Support
Selfinside fields that use serialize_with (#1970)
-
Add IntoDeserializer impl for &[u8] (#1898, thanks @Mingun)
-
Handle unrecognized numeric field keys during deserialization of a field_identifier, equivalently to string field keys (#1914, thanks @Mingun)
-
Add attribute to override default deserialization failure expectation message (#1916, thanks @Mingun)
#[derive(Deserialize)] #[serde(untagged, expecting = "single version or array of versions")] struct VersionSpec { One(Version), Many(Vec<Version>), } -
Improve
serde_testhandling of map entries and error message construction (#1918, thanks @Mingun) -
Produce more accurate location information on test failures from
serde_testcrate (#1920, thanks @Mingun) -
Improve diagnostic on failure to parse a
rename_allattribute (#1960, #1961) -
Eliminate unnecessary trait bounds on some value Deserializer impls (#1963)
- Support borrowed data during deserialization of a field identifier (#1917, thanks @Mingun)
- Fix panic when deserializing
Durationwith nanoseconds that cause the seconds counter to overflow (#1958, thanks @jonasbb)
- Fix deserialization of ignored fields containing 128-bit integer (#1955, thanks @TheJokr)
- Support serialization of core::num::Wrapping in no_std mode (#1926, thanks @attente)
- Allow serialization of std::net::SocketAddrV6 to include a scope id if present (based on https://github.com/rust-lang/rust/pull/77426)
- Fix deserialization of IpAddr, SocketAddr, Bound, Result, OsString in formats which process variant identifiers as u64 (#1888, thanks @joshtriplett)
- Support
#[serde(flatten)]on a field whose type is a type parameter and concrete type is()(#1873)
- Improve
packedrepr matching to support deriving Serialize for structs havingrepr(C, packed)(#1813, thanks @TannerRogalsky)
- Improve diagnostic when a serde trait is not implemented (#1827, thanks @taiki-e)
- Support
serde(flatten)on map types where the Serializer only works with serialize_entry (#1837)
- Process borrowed lifetimes inside of interpolated macro_rules metavariables, such as in the case of
#[derive(Deserialize)] struct S<'a> { field: $field }(#1821)
- Support deriving Serialize impl for a
repr(packed)struct (#1791, thanks @alvardes)
- Allow adjacently tagged newtype variants containing
Optionto omit the content field when deserializing (#1553, #1706, thanks @zth0) - Avoid panicking when a SystemTime older than UNIX_EPOCH is serialized (#1702, thanks @hjiayz)
-
Provide a
Serializerimpl that can write primitives and unit variants to a&mut fmt::Formatter(#1705, thanks @jethrogb)use serde::Serialize; use std::fmt::{self, Display}; #[derive(Serialize)] #[serde(rename_all = "kebab-case")] pub enum MessageType { StartRequest, EndRequest, } impl Display for MessageType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.serialize(f) } }
- Fix panic during macro expansion when using
serde(skip)andserde(other)in the same enum (#1804)
- Hide dummy const implementation detail from rustdoc when documenting a binary crate (#1768, thanks @robo9k)
- Allow #[serde(borrow)] to work on non-standard
Cowtypes (#1754, thanks @maciejhirsz)
- Revert stabilization of Serialize/Deserialize impls for
!to account for https://github.com/rust-lang/rust/pull/67224
- Support deserializing untagged unit variants from formats that treat unit as None (#1668)
- Support deserializing
PathBuffrom bytes like&Pathalready did, and support deserializingBox<Path>(#1656, thanks @heftig)
-
Report errors on malformed serde attributes, like
#[serde(rename =)]-- the compiler used to reject these itself, but when the compiler relaxed its requirements on attribute syntax these malformed attributes began silently being ignored by serde_derive -
Eliminate unused variable warning when using skip_serializing inside a tuple variant of an adjacently tagged enum (#1617, thanks @arilotter)
-
Support skip attribute inside of newtype variants (#1622, thanks @Xaeroxe)
-
Provide
serde::ser::StdErrorandserde::de::StdErrorwhich are either a re-export ofstd::error::Error(if Serde's "std" feature is enabled) or a new identical trait (otherwise).#[cfg(feature = "std")] pub use std::error::Error as StdError; #[cfg(not(feature = "std"))] pub trait StdError: Debug + Display { fn source(&self) -> Option<&(StdError + 'static)> { None } }Serde's error traits
serde::ser::Errorandserde::de::Errorrequirestd::error::Erroras a supertrait, but only when Serde is built with "std" enabled. Data formats that don't care about no_std support should generally provide their error types with astd::error::Errorimpl directly:#[derive(Debug)] struct MySerError {...} impl serde::ser::Error for MySerError {...} impl std::fmt::Display for MySerError {...} // We don't support no_std! impl std::error::Error for MySerError {}Data formats that do support no_std may either have a "std" feature of their own as has been required in the past:
[features] std = ["serde/std"]#[cfg(feature = "std")] impl std::error::Error for MySerError {}... or else now may provide the std Error impl unconditionally via Serde's re-export:
impl serde::ser::StdError for MySerError {}
-
Update Syn dependency to 1.0.
Note: This raises the minimum required compiler version for serde_derive from rustc 1.15 to rustc 1.31. The minimum required compiler version for serde remains at rustc 1.13.
- Add support for NonZeroI* types (#1589, thanks @Flaise)
-
Introduce
serde(try_from = "...")attribute to derive Deserialize based on a given implementation ofstd::convert::TryFrom(#1526, thanks @fanzeyi)#[derive(Deserialize)] #[serde(try_from = "u32")] enum N { Zero, One, Two, } impl TryFrom<u32> for N { type Error = String; fn try_from(u: u32) -> Result<Self, Self::Error> { match u { 0 => Ok(Self::Zero), 1 => Ok(Self::One), 2 => Ok(Self::Two), other => Err(format!("out of range: {}", other)), } } }
- Implement serialization and deserialization for std::sync::atomic types (#1572 and #1581, thanks @Roguelazer)
- Make "alloc" feature work on stable Rust 1.36+ (#1576, thanks @c410-f3r)
yanked
- Accept enums in input data when deserializing IgnoredAny (#1558)
- Allow integer keys in untagged flattened map (#1545)
- Support using
serde(flatten)in no_std + alloc mode (#1543, thanks @jplatte)
- Support deserializing from MapAccessDeserializer into an enum (#1522)
-
Add an attribute
#[serde(crate = "path::to::serde")]which replaces the use ofextern crate serdein the generated code; this is intended for crates that invoke Serde derives from a macro and need to refer toserdethrough their own re-export rather than requiring callers to list Serde in Cargo.toml (#1499, thanks @sgrif)#[derive(Deserialize)] #[serde(crate = "__tw::codegen::serde")] struct S { ... }// expands to: impl<'de> __tw::codegen::serde::Deserialize<'de> for S { ... }
- Implement Serialize and Deserialize for core::cmp::Reverse<T> (#1486, thanks @vorot93)
- Fix a Clippy lint triggered within generated code involving flatten + deny_unknown_fields (#1492, thanks @thomaseizinger)
- Support
flattenandskip_serializing/skip_deserializingattributes on the same field
- Fix inclusion of tag in struct containing flattened fields (#1468, thanks @jwillbold)
- Implement Serialize and Deserialize for core::ops::Bound<T> (#1466, thanks @0nkery)
-
Accept
#[serde(alias = "...")]attribute on fields and variants which allows the same field or variant to be deserialized from any of multiple different names in the input (#1458, thanks @Lymia)#[derive(Deserialize)] struct S { #[serde(alias = "old_name")] new_name: String, // will deserialize from either of "old_name" or "new_name" }
- Update example code in documentation to 2018 edition
-
Support a
rename_allspecification that applies only to the Serialize impl or only to the Deserialize impl (#1447, thanks @vincascm)#[derive(Serialize, Deserialize)] #[serde(rename_all( serialize = "camelCase", deserialize = "SCREAMING_SNAKE_CASE", ))] struct S { /* ... */ } -
Allow serializing struct name inside of structs with named fields (#1448, thanks @motu42)
#[derive(Serialize)] #[serde(tag = "type")] struct S { /* ... */ } // serializes as {"type":"S",...}
- Support
serde(default)attribute inside of tuple structs and tuple variants (#1442, thanks @tcr)
- Better error messages when using an invalid combination of serde attributes (#1424, thanks @hcpl)
- Support deserializing tagged enums inside of untagged enums in formats that encode tagged enum variants by index, like MessagePack (#1437, thanks @daboross)
- Performance optimization for
Vec::deserialize_in_placeto deserialize elements in place (#1411)
-
Add
serde(other)variant attribute for deserializing any variant that is not one of the others (#1382)#[derive(Deserialize)] #[serde(tag = "variant")] enum MyEnum { A(ModelA), B(ModelB), #[serde(other)] Unknown, }In this internally tagged enum the
MyEnum::Unknownvariant would be produced if the"variant"tag in the input is neither"A"nor"B".This feature is currently limited to externally tagged and adjacently tagged enums in which the
othervariant is a unit variant.
- Fix panic deserializing flattened Value after flattened struct (#1379)
- Fix internally tagged enum deserialization with unknown fields (#1376, thanks @dreid)
- Provide impls for
NonZeroU128(#1371, thanks @hcpl)
- Adjust dependency version requirement to support building with
-Z minimal-versionsin CI (#1367)
- Disable i128 integers on Emscripten targets (#1365, thanks @koute)
- Fix the names of serialized fields when the Rust data structure uses a raw identifier (#1362)
- Fix compilation of
default-features = false, features = ["alloc", "rc"]feature combination (#1359, thanks @Pratyush)
- Provide impls for
core::ops::RangeInclusive(#1347, thanks @c410-f3r) - Provide impls for
core::ops::Rangewhether or not"std"feature is enabled (#1348)
- Update
--features allocto work with nightly-2018-07-07 (#1335)
- Support Rust 2018
use_extern_macros(https://github.com/rust-lang/rust/pull/51496)
- Suppress 'extern crate' warning for rust 2018 (#1324, thanks @jechase)
- Implement Serialize for core::fmt::Arguments (#1319)
- Implement Serialize and Deserialize for
!(#544, unstable) - Support Duration in no-std mode on sufficiently new compilers (#1123)
- Improve compiler error messages (#1297, thanks @adamcrume)
- Do not panic when serializing a RefCell that is currently mutably borrowed (#1300, thanks @xfix)
- Allow flattened fields after a flattened map to receive input fields (#1299)
- Second attempt to work around docs.rs old compiler version (#1295)
- Workaround to get docs.rs successfully building our docs with its old compiler (#1294)
- Implement
IntoDeserializerfor i128 and u128 (#1280) - Implement Copy for the primitive value deserializers (#1287)
- Implement Clone for primitive value deserializers even when the error type cannot be cloned (#1287)
- Stabilize Deserialize impls for dynamically sized Rc / Arc (#1266)
- Stabilize Deserialize impl for Box<CStr> (#1267)
- Add Serde impls for i128 and u128 when compiling with Rust 1.26+ (#1263)
- Stabilize Serde impls for std::num::NonZero* on Rust 1.28+ (#1278, thanks @SimonSapin)
- Add a
serde(transparent)container attribute to indicate that a struct serializes and deserializes the same as its only field -- analogous torepr(transparent)(#1054)
- Fix generated code for deserializing untagged newtype variant (#1268)
- Remove unstable Serialize and Deserialize impls for
NonZero<T>which has been removed from the most recent nightly compiler (#1265)
- Add a Serde build.rs script for rustc version detection in preparation for adding i128 / u128 primitive support on sufficiently new compilers. Please let us know in #1136 if having a build script causes undue complication in your environment. We will begin using the build script to enable observable functionality after a week or so, at which point it will become harder to roll back.
- Support formats that want to deserialize flattened identifiers as bytes (#1257)
- Support flattened untagged Options in struct fields (#1255)
- Support deserializing flattened untagged enum (#1253)
- Allow overriding inferred bounds at the variant level using a
boundattribute (#1149) - Respect
skip_serializingattribute in tuple structs and variants (#1048) - Account for
skip_serializing_ifin computing tuple struct lengths (#1049) - Improve error for struct deserialized from array that is too short (#981)
- Accept implicitly borrowed data inside of an
Optionfield (#1029)
- Fix the Deserialize implementation generated for an adjacently tagged enum with zero variants (#785)
- Improve error message when deriving Deserialize for a type that already has a
'delifetime (#893) - Add a
#[serde(skip)]variant attribute to combine theskip_serializingandskip_deserializingvariant attributes that already existed - Respect variant skip attributes when inferring type parameter bounds (#892)
- Detect unsupported use of Deserialize on a dynamically sized struct ending in slice field (#830)
- Add serialize and deserialize impls for
std::rc::Weakandstd::sync::Weak(#1251)
- Fix Serialize impl of an adjacently tagged empty tuple variant or struct variant (#1247)
- Support
flattenattribute inside of enums (#1206)
- Support deserializing a flattened internally tagged enum (#1189)
- Fix dead code warnings when generating remote impls (#976)
- Respect
deserialize_withused together withflatten(#1240)
- Fix handling of newtype struct inside of an untagged enum in serde_test (#1233)
- Optimizations for binary size (#1227, #1228, #1229)
- Allow integers in an internally tagged enum to be deserialized from CBOR integers of any size (#1222)
- More flexible deserialization of byte arrays inside of untagged and internally tagged enums (#1217, #1216)
- Implement deserializer hints in handling of untagged and adjacently tagged enums to improve compile time and executable size (#286)
- Infer trait bounds for use of a type parameter associated type (#1213, thanks @Osspial)
- Fix deserialize_with on a struct variant with one field (#1215)
- Better error messages for unsupported uses of
serde(flatten)(#1204 and #1205, thanks @mitsuhiko)
- Emit working code in the case of
remote = "Self"attribute (#1196)
- Implement Serialize and Deserialize for unsigned std::num::NonZero* types (#1191, tracking issue https://github.com/rust-lang/rust/issues/49137, thanks @SimonSapin)
- Add a
flattenattribute to remove one level of structure between the serialized representation and the Rust data structure; more details in struct flattening (#1179, thanks @mitsuhiko)
- Fix parsing of
Self-qualified paths like"<[_]>::serialize"withinserialize_withattributes
- Fix derive expansion for structs containing
&stror&[u8]with missing lifetime parameter (#1176)
(yanked)
- Fix borrowed
Cow<[u8]>deserializing from non-UTF8 bytes (#1175, thanks @daboross)
- Fix unused parentheses warning in generated code (#1172)
- Update to Syn 0.12 which allows serde_derive to handle new Rust syntax that has been added within the past year
- Report conflicts between the tag of an internally tagged enum and any of the variant field names, or between the tag and content field of an adjacently tagged enum (#1170, thanks @H2CO3)
- Add
"UPPERCASE"option to#[serde(rename_all = "...")](#1132, thanks @Lireer)
- Extend Serialize and Deserialize impls on
PhantomDatato work forT: ?Sized
-
Add the following function with default implementation to the
Deserializetrait (thanks @Gankro!)fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error> where D: Deserializer<'de>, { *place = Deserialize::deserialize(deserializer)?; Ok(()) }This is a power user feature that allows deserialization to reuse existing allocations for types like
StringandVec. Enable thedeserialize_in_placefeature of serde_derive to generate these efficient implementations for all types that use#[derive(Deserialize)].extern crate serde; extern crate serde_json; use serde::Deserialize; fn main() { let mut v = Vec::<i32>::with_capacity(128); assert_eq!(v.capacity(), 128); let j = "[1, 2, 3]"; let ref mut de = serde_json::Deserializer::from_str(j); Deserialize::deserialize_in_place(de, &mut v).unwrap(); assert_eq!(v, [1, 2, 3]); assert_eq!(v.capacity(), 128); }
- Fix delegation of a skipped field's default value to the container's Default impl (#1105, thanks @Binero)
- Improve performance of array deserialization (#1106, thanks @khuey)
- Revert a change that caused serde_test deserialization tests using skipped fields to fail (#1096)
- Fix
#[derive(Deserialize)]used with#
- Fix deserialization of untagged newtype variant containing externally tagged struct variant in formats that represent struct variants as a sequence (#1093, thanks @alex-shapiro)
- Print the contents of the expected token when a serialize assert fails (#1086, thanks @Marwes)
- Catch wrong field names length in serde_test (#1090)
- Allow
borrowattribute on newtype variants (#929) - Fix bounds for macro named the same as a type parameter (#1081)
- Add an API for making tests for readable/compact representations (#1084, thanks @Marwes)
- Allow internally tagged newtype variant containing unit struct (#1085)
- Fix handling of borrowed lifetimes in fields that are skipped during deserialization (#1078, thanks @epage)
- Add impls for
std::num::Wrapping(#1072, thanks @LinearZoetrope)
- Add
Serializer::is_human_readableandDeserializer::is_human_readablewhich allow types like IpAddr to serialize in a human-readable representation in formats like JSON but in a compact binary representation in formats like Bincode (#1044, thanks @Marwes)
- Support for deserializing internally tagged enums in MessagePack (#1058)
- Generate code without warnings when a struct contains a &'static field (#1052)
- Fix errors in generated code when compiling with
deny(trivial_numeric_casts)(#1053)
- Allow the tag of a field or enum variant to be deserialized from any unsigned integer type (#963, thanks @sfackler)
- Support
serialize_withanddeserialize_withapplied to entire enum variants (#1015, thanks @spinda) - Add an optional
skip_fieldmethod so serializers can be notified when a field is skipped (#1022, thanks @sfackler) - Add a "SCREAMING-KEBAB-CASE" option for the
rename_allattribute (#1043, thanks @greyblake)
- Implement Serialize for Rc<T> and Arc<T> where T: ?Sized (#1038)
- Implement Deserialize for Rc<T> and Arc<T> where Box<T>: Deserialize (#1039)
- Make remote derive usable from outside of the module containing the remote definition (#1001)
- Update
NonZerodeserialization to account for constructor changes in nightly (#1003)
- Implement Serialize and Deserialize for
std::time::SystemTime(#949, thanks @WiSaGaN)
- Fix inferred Deserialize bounds in remote derive (#972)
- Combine the unstable
collectionsandallocfeatures to align with https://github.com/rust-lang/rust/pull/42648
- Add a
#[serde(skip)]field attribute which unifiesskip_serializingandskip_deserializing(#935, thanks @spikefoo)
- Add
BorrowedStrDeserializerandBorrowedBytesDeserializerwhich act likeIntoDeserializerimplementations for&'de strand&'de [u8](#940, thanks @BurntSushi)
Add a(mistakenly omitted from 1.0.6, this feature is in 1.0.8)#[serde(skip)]field attribute which unifiesskip_serializingandskip_deserializing(#935, thanks @spikefoo)
- Fix a regression in deserializing internally tagged struct variants containing unit variant containing borrowed strings (#932)
- Support borrowing within internally tagged enum (#926)
- Implement Deserialize for
&std::path::Path(#924, thanks @pshc)
- Make adjacently tagged enums honor deny_unknown_fields (#905, thanks @TedDriggs)
- Remove usage of unstable core::num::Zero, which was removed upstream (#898, thanks @SimonSapin)
[Serde website] [API documentation]
The primary focus of this release is on polish: making Serde easier to learn and more enjoyable to use. That said, this wouldn't be Serde without some amazing new features to tell you about as well.
In celebration of this milestone, I would like to highlight some of the work that has contributed toward making Serde the powerful, efficient, adaptable, convenient beast that exists today. This is the unfinished history of serialization in Rust.
- March 2011 — Patrick Walton adds support for serializing Rust object metadata into a format called EBML (reader and writer).
- November 2011 — Elly Jones adds a JSON library called std::json.
- February 2012 — Niko Matsakis creates a utility to generate serialization code for data structures, eliminating the grunt work of writing it by hand. The first serializer and deserializer traits appear. The same traits still exist practically unchanged in
rustc_serializetoday. - May 2014 — Erick Tryzelaar begins Serde, exploratory work to address some severe, foundational limitations in the standard library's approach to deserialization.
- December 2014 — Alex Crichton begins the deprecation of libserialize. It is clear that the design has a number of drawbacks, and there aren't resources to address them in time for Rust 1.0. The code is moved out of the rustc codebase into the
rustc_serializecrate. - March 2015 — Erick Tryzelaar releases Serde 0.2.0, proving decisively that the limitations in libserialize can be resolved by a better approach.
- May 2015 — Rust 1.0 is released. :cake:
- April 2017 — Serde is impressively fast, battle-tested in production use cases, and ready for a solid 1.0 release.
Thank you to more than 100 people who have contributed improvements, opened issues, provided help to others, or expressed their frustrations with Serde in a constructive way. We appreciate your continued support.
Zero-copy deserialization
Serde 1.0 adds the ability to deserialize into types that borrow from the input data. For example, this JSON document can now be deserialized efficiently and safely into the following Rust struct.
{
"fingerprint": "0xF9BA143B95FF6D82",
"location": "Menlo Park, CA"
}
#[derive(Deserialize)]
struct User<'a> {
fingerprint: &'a str,
location: &'a str,
}
The value for each field will be a string slice that refers to the correct substring of the input data. No memory is allocated for the strings and no data is copied. The same thing also works for &[u8] slices. Other types can be borrowed explicitly by using the #[serde(borrow)] attribute.
This uniquely Rust-y feature would be impossible or recklessly unsafe in languages other than Rust. The semantics of Rust guarantee that the input data outlives the period during which the output struct is in scope, meaning it is impossible to have dangling pointer errors as a result of losing the input data while the output struct still refers to it.
Zero-copy deserialization is discussed in more detail on this page of the website.
Remote derive
One recurrent struggle with Serde is needing to use types from somebody else's crate where they do not provide Serialize and Deserialize impls.
Rust's "orphan rule" allows writing a trait impl only if either your crate defines the trait or defines one of the types the impl is for. That means if your code uses a type defined outside of your crate without a Serde impl, you resort to newtype wrappers or other obnoxious workarounds for serializing it.
Serde 1.0 now supports deriving impls for structs and enums defined in other people's crates.
// Serde calls this the definition of the remote type. It is just a copy of the
// remote type. The `remote` attribute gives the path to the actual type.
#[derive(Serialize, Deserialize)]
#[serde(remote = "nifty::Duration")]
struct DurationDef {
secs: i64,
nanos: i32,
}
// Now the remote type can be used almost like it had its own Serialize and
// Deserialize impls all along. The `with` attribute gives the path to the
// definition for the remote type. Note that the real type of the field is the
// remote type, not the definition type.
#[derive(Serialize, Deserialize)]
struct Process {
command_line: String,
#[serde(with = "DurationDef")]
wall_time: nifty::Duration,
}
Remote derive is covered on this page of the website, which also includes an example of handling a remote struct with private fields.
Documentation
Lots of new content on the Serde website. The following new pages in particular are a valuable read even for experienced Serde users.
- The Serde data model — A new way of conceptualizing Serde's role in the ecosystem and its type system.
- Understanding deserializer lifetimes — Helpful reference as you work to upgrade your libraries to Serde 1.0.
- Writing a data format — A complete serializer and deserializer implementation annotated with an explanation of all the pieces.
Is Serde done?
As of this release, Serde is stable but not done. We say with confidence that Serde is the best serialization solution that we can design for the Rust language as it exists today and for the broad range of use cases that we target.
The Serde issue tracker has a long list of planned enhancements for you to look forward to and maybe help us implement. For the first time, none of them involve further breaking changes.
Breaking changes
-
Zero-copy deserialization involves tracking a
'delifetime.The
DeserializeandDeserializertraits as well as some other deserialization-related traits now have a'delifetime parameter. These lifetimes enable Serde to perform efficient and safe zero-copy deserialization across a variety of data formats. The website has a page on understanding deserializer lifetimes. -
Method
Deserializer::deserializehas been renamed todeserialize_any.The old name did nothing to clarify the purpose of this method in contrast to any of the other
Deserializertrait methods. Also the existence of a method nameddeserializeon two different Serde traits sometimes required them to be explicitly disambiguiated using UFCS. -
Deserializer-provided accessor traits have been renamed.
The SeqVisitor, MapVisitor, EnumVisitor, and VariantVisitor traits have been renamed to SeqAccess, MapAccess, EnumAccess, and VariantAccess. The old names conflicted with the
Visitortrait which plays a totally different role, and this was a source of confusion for new and even experienced Serde users. What's more, these accessor traits were never really playing the role of a visitor in any common sense. The are provided by theDeserializerto aVisitorto give it the ability to access elements of a data structure. -
Some questionable implicit type conversions are gone.
For example, a JSON
nullwill no longer successfully deserialize if the output type is a string. Such conversions violated the objective that if Serde successfully deserializes some input into a particular data structure, you can be condient that the input matches what your data structure says it should look like. -
ValueDeserializerhas been renamed toIntoDeserializer.The new name aligns with traits that play a similar role in other parts of the Rust ecosystem, such as
IntoIteratorandIntoFuture. -
The concept of a fixed-size sequence is gone in favor of tuple.
Previous versions of Serde represented fixed-size arrays like
[u64; 3]and tuples like(u64, u64, u64)as different types in the data model. From the perspective of a Serde data format the distinction between these types never matters, so fixed-size sequences have been removed from the data model. -
Method
deserialize_struct_fieldhas been renamed todeserialize_identifier.This method has existed since Serde 0.7 but has always been used for both struct fields and enum discriminants. The new name reflects that this method is used to identify what to deserialize next—whether that is to decide which field of a struct we are looking at, or which variant of an enum.
-
Variant indices during deserialization have changed from usize to u32.
Previous versions of Serde treated the index of a variant in an enum as usize while serializing and as u32 while deserializing. This inconsistency has been resolved by standardizing on u32.
-
The
serde_testToken API has been redesigned.The
serde_testcrate is great for unit testing implementations ofSerializeandDeserializewithout being tied to any particular data format. The API had stagnated over the past few releases so this redesign brings it in line with modern naming conventions and Serde concepts. -
Built-in visitors are private.
The
Visitorimplementations used for deserializing standard library types have been made private. These are an implementation detail and were not designed to be used by other crates. -
Byte-related wrapper types have moved to the
serde_bytescrate.The
BytesandByteBufwrappers are a stopgap solution until specialization enables us to handle&[u8]andVec<u8>in an optimized way by default. -
Size hint methods have changed from (lower, upper) bounds to Option<usize>.
The size hint on the standard library
Iteratortrait returns lower and upper bounds in order to optimize handling of complicated iterator chains. This use case never arises during Serde deserialization; the deserializer either knows the exact length of a sequence or map or has no idea. -
Rc and Arc impls require opting in to a feature.
Serialization of the reference-counted types
Rc<T>andArc<T>was a source of confusion. A single Rc could be serialized multiple times as part of a data structure, then deserialize to multiple copies of itself. If this is the behavior you want, opt in to these impls by enabling the"rc"feature of your Serde dependency.
- Remove usage of unstable core::num::Zero, which was removed upstream (#899, thanks @SimonSapin)
- Implement Serialize and Deserialize for Cell<T>, RefCell<T>, Mutex<T>, RwLock<T> (#882, thanks @jethrogb)
-
Add
#[serde(into = "T")]to serialize using the implementation ofInto<T>and#[serde(from = "T")]to deserialize using the implementation ofFrom<T>(#817, thanks @jbaublitz)#[derive(Serialize, Deserialize)] #[serde(into = "u32", from = "u32")] struct Ipv4Addr { /* ... */ } -
Implement Deserialize for
Box<CStr>on nightly (#811, thanks @jonhoo) -
Implement Serialize and Deserialize for
OsStringand implement Serialize forOsStr(#824, thanks @alexcrichton) -
Implement Serialize for
Range(#813, thanks @rocallahan)
- Implement Serialize and Deserialize for
CStringand implement Serialize forCStr(#801, thanks @jonhoo) - Provide
Serializer::collect_strto enable zero-allocation serialization of dynamically constructed strings (#789, thanks @nox)
-
Add a
rename_allattribute to rename all the fields of a struct or struct variant, or all the variants of an enum.#[derive(Serialize, Deserialize)] #[serde(rename_all = "camelCase")] struct S { first_field: u8, // gets renamed to firstField second_field: u8, // gets renamed to secondField }The possible renames are:
#[serde(rename_all = "PascalCase")]#[serde(rename_all = "camelCase")]#[serde(rename_all = "snake_case")]#[serde(rename_all = "SCREAMING_SNAKE_CASE")]#[serde(rename_all = "kebab-case")]
- Fix a bug causing externally tagged enums inside of untagged / internally tagged enums to fail to deserialize (#775 and https://github.com/serde-rs/json/issues/248)
-
Add
with = "..."attribute that serves as a combination of serialize_with and deserialize_with (#763)#[derive(Serialize, Deserialize)] struct MyStruct { - #[serde(serialize_with = "hyper_serde::serialize", - deserialize_with = "hyper_serde::deserialize")] + #[serde(with = "hyper_serde")] headers: Headers, }Whatever path you give, Serde will use
$path::serializeas the serializer and$path::deserializeas the deserializer. -
Haskell / Pandoc style adjacently tagged enums (#758, thanks @elliottslaughter)
#[derive(Serialize, Deserialize)] #[serde(tag = "t", content = "c")] enum MyType { One(String), Two(u8, u8), }Written in JSON syntax, this enum would be represented as:
{ "t": "One", "c": "whatever string" } { "t": "Two", "c": [127, 1] } -
Allow
serde(default)attribute on structs (#780, thanks @Thomasdezeeuw)#[derive(Serialize, Deserialize)] #[serde(default)] struct StructDefault { a: i32, b: String, } impl Default for StructDefault { fn default() -> Self { StructDefault { a: 100, b: "default".to_string(), } } } -
Clamp size hints coming from untrusted input to 4096 (#774, thanks @nox)
This mitigates some types of attacks where untrusted input can instigate the allocation of large vectors or maps.
-
Optimize the serialization of various std::net types (#778, thanks @SimonSapin)
-
Add
Serializer::collect_seqandSerializer::collect_mapto simplify some Serialize impls (#736)- let mut map = serializer.serialize_map(Some(self.len()))?; - for (k, v) in self { - map.serialize_key(k)?; - map.serialize_value(v)?; - } - map.end() + serializer.collect_map(self)
- Support for untagged and internally tagged enum representations; see the manual for details (#739)
- Remove Serialize and Deserialize impls for collections::enum_set::EnumSet which has been deprecated for a long time (#740)
- Fix compilation errors in generated code when Ok or Err were redefined from their usual meaning within the same module (#737)
- Remove clippy dependency to unblock the documentation build in docs.rs
- Provide
serde::ser::Impossible, a helper for Serializer implementations that do not support serializing one of the compound types (#694)
- Fix invalid-length error message for arrays and tuple that incorrectly claimed the length was always 0
- Add
SerializeMap::serialize_entryto allow serializers to optimize for the case where key and value are both available at the same time (#724)
- Bump the
serdedev-dependency onserde_derive- see this forum thread
In the six months since Serde 0.8.0 we have learned a lot about how people use Serde, how people wish they could use Serde, and the common failure modes when people try to use Serde.
The primary focus of 0.9.0 is on using Rust's type system to enforce contracts that were implicit and fragile in previous Serde versions. All four of the Serialize, Deserialize, Serializer, and Deserializer traits have been redesigned to use ownership as a way to enforce that implementations are correct.
Another exciting improvement is a redesigned error-reporting API that produces substantially more helpful error messages. The new API supports no_std as a first-class citizen, meaning no_std users are now able to receive the same helpful messages as std. Speaking of no_std, #[derive(Serialize, Deserialize)] now works within no_std crates.
Serde 0.9.0 is a huge release compared to previous ones. Thank you to dozens of people who have contributed improvements, opened issues, provided help to others, or expressed their frustrations with Serde in a constructive way. We appreciate your continued support as we pin down what a 1.0.0 data structure serialization library for Rust should look like.
This release includes serde_codegen for Rust 1.14 and earlier users. With Macros 1.1 custom derives being stabilized next week in Rust 1.15, we will not be releasing any further 0.9.x versions of serde_codegen. Please migrate to serde_derive at your convenience. See the manual for steps.
There are no silent breaking changes in this release. As you work to update your libraries, the compiler will tell you everything that needs to be changed.
Users of serde_json should read also the serde_json 0.9.0 release notes. This is a great release for serde_json, including a powerful new json! macro.
Breaking changes
-
The signature of
Serialize::serializehas changed.- fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> - where S: Serializer; + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where S: Serializer;Together with the Serializer changes in this release, the new signature enforces that the implementation makes exactly one serializer method call. In previous Serde versions, an incorrect Serialize implementation could invoke the serializer not at all or more than once, resulting in a correctly-written serializer producing syntactically invalid output.
-
The signature of
Deserialize::deserializehas changed.- fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error> - where D: Deserializer; + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where D: Deserializer;Same reason as the Serialize change.
-
The
Serializercomes with an associated typeS::Ok.All Serializer methods return this type and it is propagated by the Serialize trait as you can see above. The various Serializer methods have changed like this:
- fn serialize_bool(&mut self, v: bool) -> Result<(), Self::Error>; + fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;The change from
&mut selftoselfis how the Serialize trait enforces at most one call to a serializer method, and the associated type S::Ok is how the Serialize trait enforces at least one call to a serializer method. Together these changes enforce a correct Serialize implementation.Most serializers that produce binary or text data as output or write to a stream will want to set
Ok = (). In some cases serializers that build in-memory data structures as output may benefit from using a differentOktype. For example serde_json provides a Serializer that turns a type T into serde_json::Value (this is distinct from the main serde_json Serializer that produces JSON text). This Serializer is vastly simplified by usingOk = serde_json::Valuecompared to its previous implementation.The change from
&mut selftoselfmeans that many Serializers will want to change their implementation fromimpl Serializer for SomeThingtoimpl<'a> Serializer for &'a mut SomeThing. -
The serialization scheme for compound types has changed.
This does not affect types that use
#[derive(Serialize)]. It affects types that provide custom implementations ofSerializeand serialize into one of the compound types: sequence, tuple, tuple struct, tuple variant, map, struct, or struct variant.For example to serialize a sequence type like
Vec<T>:- let mut seq_state = serializer.serialize_seq(Some(self.len()))?; - for element in self { - serializer.serialize_seq_elt(&mut seq_state, element)?; - } - serializer.serialize_seq_end(seq_state) + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for element in self { + seq.serialize_element(element)?; + } + seq.end()The new scheme is more concise and uses ownership to enforce a correct implementation. It is impossible to forget to call
end()because you cannot get anS::Okinstance otherwise. Previously, forgetting to callserialize_seq_endwould often result in broken output from the serializer. -
The pointer-sized
usizeandisizetypes are no longer part of the Serde data model.Rust's usize and isize types are still supported but will be serialized as u64 and i64 from the perspective of a
SerializerandDeserializerimplementation. -
The
ser::Errorandde::Errortraits have been redesigned.The new design is able to produce substantially more helpful error messages and supports no_std as a first-class citizen without sacrificing usability for std users.
- Invalid type. Expected `I64` + invalid type: integer `99`, expected a string - Unknown variant `X` + unknown variant `X`, expected one of `A`, `B`, `C` - Invalid length: 1 + invalid length 1, expected a tuple of 2 elementsPlease see the API documentation for details.
-
A new stateful deserialization API.
A DeserializeSeed trait has been added to handle cases where deserialization needs to depend on some pre-existing piece of state (the "seed"). One possible application of this API is for deserialization that writes into an existing previously allocated buffer rather than allocating a fresh buffer for every element. The existing buffer can be used as a "seed" that the DeserializeSeed implementation can write into.
This API dramatically simplifies
serde-transcodeand other streaming deserialization use cases, eliminating the need for unsafe code in many situations.Refer to the API documentation for a complete example.
-
The
end()method has been removed fromSeqVisitorandMapVisitor.This affects custom implementations of Deserialize that deserialize from a sequence or map type. The
end()method was too easy to forget to call and it was ambiguous whether it needed to be called on various error codepaths. -
The enum deserialization API has been simplified.
This affects custom implementations of Deserialize that process enum types. The new enum API is now much more similar to the sequence and map deserialization APIs and some convoluted indirection has been cleaned up.
- Add categories to crates.io (#707, thanks @shepmaster)
- Remove
#![feature(proc_macro)]feature gates to support serde_derive on the beta channel! - Support deserializing a
ByteBuffrom a string (#645)
-
Implement skip_serializing for enum variants (#653, thanks @shinglyu)
#[derive(Serialize)] enum E { A(bool), B(String), #[serde(skip_serializing)] C(NotSerializable), }Serialization will fail with a message if that particular variant is the one being serialized.
"The enum variant E::C cannot be serialized"
-
Implement skip_deserializing for enum variants (#641, thanks @shinglyu)
#[derive(Deserialize)] enum E { A(bool), B(String), #[serde(skip_deserializing)] C(NotDeserializable), }
Support for rustc 1.15.0-nightly (7b3eeea22 2016-11-21)
Support for rustc 1.15.0-nightly (ac635aa95 2016-11-18)
Support for rustc 1.14.0-nightly (7c69b0d5a 2016-11-01)
- Fix possible warning when building with
#
- Use post-expansion tricks to make serde attributes available to other custom derives like elastic_types_derive (#592)
- Fix corrupted deserialization code being generated randomly when using serde_codegen (did not affect serde_derive) #590
- The empty array
[T; 0]now supports deserializing from formats that handle fixed-sized arrays only (#582) - The empty array
[T; 0]no longer requiresT: Defaultin order to deserialize (#583)
- Update the serde_derive crate type from "rustc-macro" to "proc-macro" to match the blanket rename in Rust (https://github.com/rust-lang/rust/pull/36945). Rustc 1.14.0-nightly (6e8f92f11 2016-10-07) is the first version containing the rename.
This release deprecates the old Serde compiler plugin serde_macros in favor of the Macros 1.1-based implementation serde_derive.
We do not intend to release any further version of serde_macros, not even to fix breakage in future nightly versions. The design of Macros 1.1 is such that we do not expect to see the regular breakage with serde_derive that we used to see with serde_macros, as it depends on a far more limited set of unstable compiler internals.
See https://serde.rs/codegen-nightly.html for steps to set up serde_derive, or https://serde.rs/codegen-hybrid.html for steps to set up a hybrid serde_codegen/serde_derive approach that works on stable.
Old approach
[dependencies]
serde_macros = "0.8"
#![feature(plugin, custom_derive)]
#![plugin(serde_macros)]
New approach
[dependencies]
serde_derive = "0.8"
#![feature(rustc_macro)]
#[macro_use]
extern crate serde_derive;
// everything else is the same
Support for rustc 1.13.0-nightly (1265cbf4e 2016-09-15)
- Fix faulty generated code when using a
serialize_withfield attribute along with a nonstandardResulttype in the same module (#546)
-
Add a
forward_to_deserialize!macro to simplify JSON-likeDeserializerimplementations that want to ignore type hints given byDeserialize(#525)impl Deserializer for MyDeserializer { fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error> where V: Visitor { /* ... */ } forward_to_deserialize! { bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string unit option seq seq_fixed_size bytes map unit_struct newtype_struct tuple_struct struct struct_field tuple enum ignored_any } } -
Add constructors for the
BytesandByteBufhelpers (#520) -
Allow
MapDeserializerto be deserialized as a sequence of pairs instead of a map (#527) -
Fix warnings in generated code for a non-unit struct with no fields (#536)
-
Minor cleanup of generated serialization code (#538)
- Add a
serde_derivecrate which provides a Macros 1.1 implementation of#[derive(Serialize, Deserialize)](#530) - Add
serde_codegen::expand_strwhich is necessary for Macros 1.1
Using Macros 1.1 requires rustc support (not in nightly yet but available in https://github.com/rust-lang/rust/pull/35957) and cargo support (available in https://github.com/rust-lang/cargo/pull/3064). Using Macros 1.1 looks like this:
Cargo.toml
[dependencies]
serde = "0.8"
serde_derive = "0.8"
src/main.rs
#![feature(rustc_macro)]
#[macro_use]
extern crate serde_derive;
#[derive(Serialize, Deserialize)]
struct ItWorks {
exciting: bool,
}
Advantages of this approach:
- We expect Macros 1.1 to be stabilized much sooner than the features that serde_macros relies on, so we are finally in sight of having ergonomic Serde code generation available on stable Rust.
- Even on nightly Rust, serde_derive is built in a way that is much more stable than serde_macros. It will not be affected by breaking libsyntax changes in the nightly compiler.
Support for rustc 1.13.0-nightly (eac41469d 2016-08-30)
- Implement ValueDeserializer for
Cow<str>(#513) - Support maps of unknown size in MapDeserializer (#514)
- Fixes codegen for structs that have a lifetime parameter but no generic type parameter (#507)
- Using Syntex,
serde_codegen::expandnow runs with a 16 MB stack by default because the previous default was often insufficient (#494, #503)
- Impl Serialize and Deserialize for std::time::Duration (#476)
- Use a thread in the build script of serde_codegen to allow env vars to control the stack size (#488)
This release contains significant breaking changes compared to v0.7.x.
Traits
-
The Serializer trait has been modified to allow for streaming serialization - serializing seq and map elements before knowing what the end of the seq or map will be. (#437)
-
Reduced boilerplate (no more SeqVisitor and MapVisitor) when implementing Serialize for most types.
// OLD API struct MySeqVisitor { /* ... */ } impl /* pages of boilerplate */ try!(serializer.serialize_seq(MySeqVisitor::new(iter, len))); // NEW API let mut state = try!(serializer.serialize_seq(len)); for e in iter { try!(serializer.serialize_seq_elt(&mut state, e)); } try!(serializer.serialize_seq_end(state)); -
The Serializer and Deserializer traits no longer provide default implementations for any methods. The old defaults were JSON-centric and inappropriate for most other formats. Every Serializer and Deserializer should mindfully implement all of the methods. (#437, #452)
Codegen
- No more public dependency on Syntex. The
serde_codegen::registerfunction which was deprecated in v0.7.9 has been removed. Users should useserde_codegen::expand. See the readme for sample code, and see this forum topic for exposition. (#445) - Adjusted heuristic for generating bounds on generic type parameters (#456). This fixes a number of issues relating to bounds on recursive types, bounds involving references, and bounds involving private types (#435, #436, #441, #443)
Impls
- The Deserialize impl for
PhantomData<T>has been expanded to allT, not justT: Deserialize(#457, #459) - Add Deserialize impl for
Box<str>(#454)
Nightly
- The
nightlyfeature has been renamed tounstableto align with community practices. (#404)
(this release is a Syntex bump only)
(this release is a Syntex bump only)
- Excludes generated code from Clippy lints (rust-clippy#969)
- Fixes the error code when deserializing a struct or enum from a seq of the wrong length (#421)
(this release is a Syntex bump only)
- Better error when attempting to derive Deserialize for a struct containing
&str(#378) - Error when a struct field has duplicate attributes (#355)
- Serialize and Deserialize impls for tuples up to 16 elements (previously only up to 12 elements) (#387)
- Adds Serialize and Deserialize support for HashMap and HashSet that use a non-default Hasher (#369)
- Adds
serde_codegen::expandas an alternative toserde_codegen::registerwhen using thewith-syntexfeature. This hides the dependency on Syntex and allows Syntex users to avoid being broken by Serde bumping its Syntex dependency. Theserde_codegen::registerfunction is deprecated and will be removed in 0.8.0. #362
- Adds a
boundattribute for specifying handwrittenwhereclause for Serialize and Deserialize impls in tricky situations (#352)#[serde(bound="D: Serialize + Deserialize")]#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]
- No longer generates bounds based on fields that contain direct recursion as this typically leads to infinite recursion in rustc (#336)
- Fixes
renameattributes canceling one another if specified separately for ser and de (#353)
- Reverts an unintentional breaking change in 0.7.6 (#349)
- Enables use in no_std environments, controlled by the following feature flags (#316)
alloc(impliesnightly)collections(impliesallocandnightly)std(default)
- Fixes a number of bugs around (de)serialize_with in newtype structs, tuple structs, newtype variants, and tuple variants (#335)
- Serializes double-references to generic types correctly (#337)
- Fixes some compiler warnings that snuck into 0.7.5 (#322)
- Fixes a codegen regression from 0.7.4 that generates invalid code for some generic structs (#308)
- Visiting the same struct field or map key twice is now an error (#293)
- Fields with
deserialize_withare no longer required to implement theDeserializetrait (#311) - Fixes a codegen bug related to
deserialize_within a struct containing more than one field (#308) - Fixes a codegen bug related to
deserialize_within a struct with a type parameter calledD(#315)
- Adds
skip_deserializingattribute (#265) - Adds Deserialize impl for
Box<[T]>(#290) - Fields with
skip_serializingare no longer required to implement theSerializetrait (#260, #285) - A bound of
std::default::Defaultis inferred for fields that use thedefaultattribute (#285) - Supports codegen for structs that use defaulted generic type params (#295)
- Supports
extern crate serdenot in the top-level module (#298)
This release contains significant breaking changes compared to v0.6.x.
Deserializer trait
- Renames
Deserializer::visit_*toDeserializer::deserialize_*(#151) - Adds
deserialize_ignored_anymethod to Deserializer trait (#225) - Overhauls the
de::Errortrait (#160, #166, #169, #249, #254) - Adds hooks for fixed-sized arrays (#244)
Attributes
- Adds
deny_unknown_fieldsattribute (#44 and #60) - Adds
default="..."attribute (#90, #216) - Removes support for format-specific renames added in v0.4.0 (#211)
- Supports serialize- and deserialize-specific renames (#233)
Impls
- Adds impls for PhantomData (#248)
- Adds impls for std::net::Ip{,v4,v6}Addr (#181)
- Removes dependency on
numcrate added in v0.6.6 (#243) - Fixes panic during serialization of Path (#57)
(this release is a Syntex bump only)
(this release is a Syntex bump only)
(this release is a Syntex bump only)
- Method
visit_struct_fieldhas been added to theDeserializertrait to hint that a struct key is expected (#223 and 064241f)
- Allow options to be deserialized from units (#217)
- Fixes panic when a non-struct/enum is annotated (#206)
- Adds a
clippyfeature to build with Clippy (bfa2b69) - An unknown serde attribute is now an error (#51, #175, #187)
(this release is a Syntex bump only)
- Adds impls for num::{BigInt, BigUint, Complex, Ratio} (#191)
- Adds attributes
skip_serializing_if_noneandskip_serializing_if_empty(c4392ff)
- Removes the unused EnumSeqVisitor and EnumMapVisitor traits (9a8037b)
- Removes the unused
bufmodule (c14eb28)