Compare commits

...

20 Commits

Author SHA1 Message Date
David Tolnay 2db2b53bbf Release 1.0.65 2018-06-01 13:00:58 -07:00
David Tolnay d5ec3efe49 Merge pull request #1299 from dtolnay/flattenmap
Allow multiple flattened maps to see the same fields
2018-06-01 13:00:45 -07:00
David Tolnay 71fc318474 Merge pull request #1300 from dtolnay/refcell
Use try_borrow for serializing RefCell
2018-06-01 12:58:03 -07:00
David Tolnay 5ee2fc0562 Allow multiple flattened maps to see the same fields
Before this change, flattening anything after a flattened map was
nonsensical because the later flattened field would always observe no
input fields.

    #[derive(Deserialize)]
    struct S {
        #[serde(flatten)]
        map: Map<K, V>,
        #[serde(flatten)]
        other: Other, // always empty
    }

This change makes a flattened map not consume any of the input fields,
leaving them available to later flattened fields in the same struct. The
new behavior is useful when two flattened fields that both use
deserialize_map care about disjoint subsets of the fields in the input.

    #[derive(Deserialize)]
    struct S {
        // Looks at fields with a "player1_" prefix.
        #[serde(flatten, with = "prefix_player1")]
        player1: Player,
        // Looks at fields with a "player2_" prefix.
        #[serde(flatten, with = "prefix_player2")]
        player2: Player,
    }
2018-06-01 12:50:23 -07:00
David Tolnay ca53daf697 Fix RefCell serialize impl to work with no-std 2018-06-01 12:47:10 -07:00
Konrad Borowski c3b9ee314b Use try_borrow for serializing RefCell 2018-06-01 09:09:40 +02:00
David Tolnay dbaf2893e3 Release 1.0.64 2018-05-30 00:17:45 -07:00
David Tolnay 34a7108b73 Second attempt at workaround for docs.rs compiler 2018-05-30 00:17:02 -07:00
David Tolnay db2bafd3f3 Revert "Work around docs.rs using an old 1.26-dev compiler"
This reverts commit c81bab18ad.
2018-05-30 00:13:20 -07:00
David Tolnay 1b6fbf1023 Release 1.0.63 2018-05-28 20:12:08 -07:00
David Tolnay c81bab18ad Work around docs.rs using an old 1.26-dev compiler 2018-05-28 19:58:27 -07:00
David Tolnay a39199e9f7 Reword Avro blurb
- Emphasize the association with Apache Hadoop,

- Rephrase "schematized data" because that term returns not many Google
  results, doesn't seem widely recognized.
2018-05-27 19:39:50 -07:00
David Tolnay b0ad1e56e8 Move Avro above deserialization-only formats 2018-05-27 19:31:05 -07:00
David Tolnay ab53448bc3 Merge pull request #1260 from flavray/master
Add Avro to the list of supported data formats
2018-05-27 19:29:19 -07:00
David Tolnay c50c9d8862 Simplify readme as rendered on crates.io 2018-05-27 19:18:30 -07:00
David Tolnay cc4f289758 Link from readme to new playground 2018-05-27 19:07:46 -07:00
David Tolnay a2a9041549 Fix warning about unresolved [u8] and [T] links 2018-05-27 14:35:55 -07:00
David Tolnay a65950acca Link to more complete explanation of the data model 2018-05-27 14:11:02 -07:00
David Tolnay 0fbf4d0c5d Link to example data format from trait rustdocs 2018-05-27 14:05:50 -07:00
Flavien Raynaud 38d4f0e06c Add Avro to the list of supported data formats 2018-05-16 16:22:25 +01:00
20 changed files with 338 additions and 51 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ You may be looking for:
<details> <details>
<summary> <summary>
Click to show Cargo.toml. Click to show Cargo.toml.
<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a> <a href="https://play.rust-lang.org/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
</summary> </summary>
```toml ```toml
+55
View File
@@ -0,0 +1,55 @@
<!-- Serde readme rendered on crates.io -->
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
---
You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
```
## Getting help
Serde developers live in the #serde channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
good resource with generally faster response time but less specific knowledge
about Serde. If IRC is not your thing or you don't get a good response, we are
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
as well.
+3 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.62" # remember to update html_root_url version = "1.0.65" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
@@ -9,8 +9,8 @@ repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde/" documentation = "https://docs.serde.rs/serde/"
keywords = ["serde", "serialization", "no_std"] keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"] categories = ["encoding"]
readme = "README.md" readme = "crates-io.md"
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] include = ["Cargo.toml", "build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
build = "build.rs" build = "build.rs"
[badges] [badges]
+5
View File
@@ -53,6 +53,11 @@ fn rustc_minor_version() -> Option<u32> {
Err(_) => return None, Err(_) => return None,
}; };
// Temporary workaround to support the old 1.26-dev compiler on docs.rs.
if version.contains("0eb87c9bf") {
return Some(25);
}
let mut pieces = version.split('.'); let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") { if pieces.next() != Some("rustc 1") {
return None; return None;
+1
View File
@@ -0,0 +1 @@
../crates-io.md
+52 -8
View File
@@ -57,7 +57,7 @@
//! - f32, f64 //! - f32, f64
//! - char //! - char
//! - **Compound types**: //! - **Compound types**:
//! - [T; 0] through [T; 32] //! - \[T; 0\] through \[T; 32\]
//! - tuples up to size 16 //! - tuples up to size 16
//! - **Common standard library types**: //! - **Common standard library types**:
//! - String //! - String
@@ -66,7 +66,7 @@
//! - PhantomData\<T\> //! - PhantomData\<T\>
//! - **Wrapper types**: //! - **Wrapper types**:
//! - Box\<T\> //! - Box\<T\>
//! - Box\<[T]\> //! - Box\<\[T\]\>
//! - Box\<str\> //! - Box\<str\>
//! - Rc\<T\> //! - Rc\<T\>
//! - Arc\<T\> //! - Arc\<T\>
@@ -86,7 +86,7 @@
//! - Vec\<T\> //! - Vec\<T\>
//! - **Zero-copy types**: //! - **Zero-copy types**:
//! - &str //! - &str
//! - &[u8] //! - &\[u8\]
//! - **FFI types**: //! - **FFI types**:
//! - CString //! - CString
//! - Box\<CStr\> //! - Box\<CStr\>
@@ -148,6 +148,13 @@ macro_rules! declare_error_trait {
/// ///
/// Most deserializers should only need to provide the `Error::custom` method /// Most deserializers should only need to provide the `Error::custom` method
/// and inherit the default behavior for the other methods. /// and inherit the default behavior for the other methods.
///
/// # Example implementation
///
/// The [example data format] presented on the website shows an error
/// type appropriate for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Error: Sized $(+ $($supertrait)::+)* { pub trait Error: Sized $(+ $($supertrait)::+)* {
/// Raised when there is general error when deserializing a type. /// Raised when there is general error when deserializing a type.
/// ///
@@ -780,10 +787,10 @@ where
/// A **data format** that can deserialize any data structure supported by /// A **data format** that can deserialize any data structure supported by
/// Serde. /// Serde.
/// ///
/// The role of this trait is to define the deserialization half of the Serde /// The role of this trait is to define the deserialization half of the [Serde
/// data model, which is a way to categorize every Rust data type into one of 29 /// data model], which is a way to categorize every Rust data type into one of
/// possible types. Each method of the `Serializer` trait corresponds to one of /// 29 possible types. Each method of the `Serializer` trait corresponds to one
/// the types of the data model. /// of the types of the data model.
/// ///
/// Implementations of `Deserialize` map themselves into this data model by /// Implementations of `Deserialize` map themselves into this data model by
/// passing to the `Deserializer` a `Visitor` implementation that can receive /// passing to the `Deserializer` a `Visitor` implementation that can receive
@@ -801,7 +808,7 @@ where
/// - UTF-8 bytes with a length and no null terminator. /// - UTF-8 bytes with a length and no null terminator.
/// - When serializing, all strings are handled equally. When deserializing, /// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed. /// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - [u8] /// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be transient, /// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed. /// owned, or borrowed.
/// - **option** /// - **option**
@@ -866,6 +873,8 @@ where
/// means your data type will be able to deserialize from self-describing /// means your data type will be able to deserialize from self-describing
/// formats only, ruling out Bincode and many others. /// formats only, ruling out Bincode and many others.
/// ///
/// [Serde data model]: https://serde.rs/data-model.html
///
/// # Lifetime /// # Lifetime
/// ///
/// The `'de` lifetime of this trait is the lifetime of data that may be /// The `'de` lifetime of this trait is the lifetime of data that may be
@@ -873,6 +882,13 @@ where
/// deserializer lifetimes] for a more detailed explanation of these lifetimes. /// deserializer lifetimes] for a more detailed explanation of these lifetimes.
/// ///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html /// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website contains example code for
/// a basic JSON `Deserializer`.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Deserializer<'de>: Sized { pub trait Deserializer<'de>: Sized {
/// The error type that can be returned if some error occurs during /// The error type that can be returned if some error occurs during
/// deserialization. /// deserialization.
@@ -1650,6 +1666,13 @@ pub trait Visitor<'de>: Sized {
/// deserializer lifetimes] for a more detailed explanation of these lifetimes. /// deserializer lifetimes] for a more detailed explanation of these lifetimes.
/// ///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html /// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SeqAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SeqAccess<'de> { pub trait SeqAccess<'de> {
/// The error type that can be returned if some error occurs during /// The error type that can be returned if some error occurs during
/// deserialization. /// deserialization.
@@ -1725,6 +1748,13 @@ where
/// deserializer lifetimes] for a more detailed explanation of these lifetimes. /// deserializer lifetimes] for a more detailed explanation of these lifetimes.
/// ///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html /// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `MapAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait MapAccess<'de> { pub trait MapAccess<'de> {
/// The error type that can be returned if some error occurs during /// The error type that can be returned if some error occurs during
/// deserialization. /// deserialization.
@@ -1910,6 +1940,13 @@ where
/// deserializer lifetimes] for a more detailed explanation of these lifetimes. /// deserializer lifetimes] for a more detailed explanation of these lifetimes.
/// ///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html /// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `EnumAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait EnumAccess<'de>: Sized { pub trait EnumAccess<'de>: Sized {
/// The error type that can be returned if some error occurs during /// The error type that can be returned if some error occurs during
/// deserialization. /// deserialization.
@@ -1950,6 +1987,13 @@ pub trait EnumAccess<'de>: Sized {
/// deserializer lifetimes] for a more detailed explanation of these lifetimes. /// deserializer lifetimes] for a more detailed explanation of these lifetimes.
/// ///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html /// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `VariantAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait VariantAccess<'de>: Sized { pub trait VariantAccess<'de>: Sized {
/// The error type that can be returned if some error occurs during /// The error type that can be returned if some error occurs during
/// deserialization. Must match the error type of our `EnumAccess`. /// deserialization. Must match the error type of our `EnumAccess`.
+4 -1
View File
@@ -52,6 +52,8 @@
//! - [Pickle], a format common in the Python world. //! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans. //! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [BSON], the data storage and network transfer format used by MongoDB. //! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//! definition.
//! - [URL], the x-www-form-urlencoded format. //! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard. //! - [XML], the flexible machine-friendly W3C standard.
//! *(deserialization only)* //! *(deserialization only)*
@@ -69,6 +71,7 @@
//! [Pickle]: https://github.com/birkenfeld/serde-pickle //! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust //! [Hjson]: https://github.com/laktak/hjson-rust
//! [BSON]: https://github.com/zonyitoo/bson-rs //! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [URL]: https://github.com/nox/serde_urlencoded //! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs //! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy //! [Envy]: https://github.com/softprops/envy
@@ -79,7 +82,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.62")] #![doc(html_root_url = "https://docs.rs/serde/1.0.65")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
+61 -15
View File
@@ -2723,7 +2723,7 @@ where
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), None)) visitor.visit_map(FlatMapAccess::new(self.0.iter()))
} }
fn deserialize_struct<V>( fn deserialize_struct<V>(
@@ -2735,7 +2735,7 @@ where
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), Some(fields))) visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields))
} }
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
@@ -2784,22 +2784,19 @@ where
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapAccess<'a, 'de: 'a, E> { pub struct FlatMapAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>, pending_content: Option<&'a Content<'de>>,
fields: Option<&'static [&'static str]>,
_marker: PhantomData<E>, _marker: PhantomData<E>,
} }
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> { impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> {
fn new( fn new(
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>, iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
fields: Option<&'static [&'static str]>,
) -> FlatMapAccess<'a, 'de, E> { ) -> FlatMapAccess<'a, 'de, E> {
FlatMapAccess { FlatMapAccess {
iter: iter, iter: iter,
pending_content: None, pending_content: None,
fields: fields,
_marker: PhantomData, _marker: PhantomData,
} }
} }
@@ -2812,6 +2809,61 @@ where
{ {
type Error = E; type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
// Items in the vector are nulled out when used by a struct.
if let Some((ref key, ref content)) = *item {
self.pending_content = Some(content);
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.pending_content.take() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
None => Err(Error::custom("value is missing")),
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatStructAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: &'static [&'static str],
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> {
fn new(
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
fields: &'static [&'static str],
) -> FlatStructAccess<'a, 'de, E> {
FlatStructAccess {
iter: iter,
pending_content: None,
fields: fields,
_marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
where
E: Error,
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where where
T: DeserializeSeed<'de>, T: DeserializeSeed<'de>,
@@ -2822,13 +2874,7 @@ where
// about. In case we do not know which fields we want, we take them all. // about. In case we do not know which fields we want, we take them all.
let use_item = match *item { let use_item = match *item {
None => false, None => false,
Some((ref c, _)) => c.as_str().map_or(self.fields.is_none(), |key| { Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)),
match self.fields {
None => true,
Some(fields) if fields.contains(&key) => true,
_ => false,
}
}),
}; };
if use_item { if use_item {
+5 -5
View File
@@ -8,10 +8,7 @@
use lib::*; use lib::*;
use ser::{Serialize, SerializeTuple, Serializer}; use ser::{Error, Serialize, SerializeTuple, Serializer};
#[cfg(feature = "std")]
use ser::Error;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -459,7 +456,10 @@ where
where where
S: Serializer, S: Serializer,
{ {
self.borrow().serialize(serializer) match self.try_borrow() {
Ok(value) => value.serialize(serializer),
Err(_) => Err(S::Error::custom("already mutably borrowed")),
}
} }
} }
+86 -7
View File
@@ -55,8 +55,8 @@
//! - str //! - str
//! - &T and &mut T //! - &T and &mut T
//! - **Compound types**: //! - **Compound types**:
//! - [T] //! - \[T\]
//! - [T; 0] through [T; 32] //! - \[T; 0\] through \[T; 32\]
//! - tuples up to size 16 //! - tuples up to size 16
//! - **Common standard library types**: //! - **Common standard library types**:
//! - String //! - String
@@ -127,6 +127,13 @@ macro_rules! declare_error_trait {
/// Trait used by `Serialize` implementations to generically construct /// Trait used by `Serialize` implementations to generically construct
/// errors belonging to the `Serializer` against which they are /// errors belonging to the `Serializer` against which they are
/// currently running. /// currently running.
///
/// # Example implementation
///
/// The [example data format] presented on the website shows an error
/// type appropriate for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Error: Sized $(+ $($supertrait)::+)* { pub trait Error: Sized $(+ $($supertrait)::+)* {
/// Used when a [`Serialize`] implementation encounters any error /// Used when a [`Serialize`] implementation encounters any error
/// while serializing a type. /// while serializing a type.
@@ -244,10 +251,10 @@ pub trait Serialize {
/// A **data format** that can serialize any data structure supported by Serde. /// A **data format** that can serialize any data structure supported by Serde.
/// ///
/// The role of this trait is to define the serialization half of the Serde data /// The role of this trait is to define the serialization half of the [Serde
/// model, which is a way to categorize every Rust data structure into one of 29 /// data model], which is a way to categorize every Rust data structure into one
/// possible types. Each method of the `Serializer` trait corresponds to one of /// of 29 possible types. Each method of the `Serializer` trait corresponds to
/// the types of the data model. /// one of the types of the data model.
/// ///
/// Implementations of `Serialize` map themselves into this data model by /// Implementations of `Serialize` map themselves into this data model by
/// invoking exactly one of the `Serializer` methods. /// invoking exactly one of the `Serializer` methods.
@@ -264,7 +271,7 @@ pub trait Serialize {
/// - UTF-8 bytes with a length and no null terminator. /// - UTF-8 bytes with a length and no null terminator.
/// - When serializing, all strings are handled equally. When deserializing, /// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed. /// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - [u8] /// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be transient, /// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed. /// owned, or borrowed.
/// - **option** /// - **option**
@@ -309,6 +316,15 @@ pub trait Serialize {
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json` /// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
/// serializer) that produces a `serde_json::Value` data structure in memory as /// serializer) that produces a `serde_json::Value` data structure in memory as
/// output. /// output.
///
/// [Serde data model]: https://serde.rs/data-model.html
///
/// # Example implementation
///
/// The [example data format] presented on the website contains example code for
/// a basic JSON `Serializer`.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Serializer: Sized { pub trait Serializer: Sized {
/// The output type produced by this `Serializer` during successful /// The output type produced by this `Serializer` during successful
/// serialization. Most serializers that produce text or binary output /// serialization. Most serializers that produce text or binary output
@@ -1520,6 +1536,8 @@ pub trait Serializer: Sized {
/// Returned from `Serializer::serialize_seq`. /// Returned from `Serializer::serialize_seq`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
@@ -1557,6 +1575,13 @@ pub trait Serializer: Sized {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeSeq` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeSeq { pub trait SerializeSeq {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
@@ -1575,6 +1600,8 @@ pub trait SerializeSeq {
/// Returned from `Serializer::serialize_tuple`. /// Returned from `Serializer::serialize_tuple`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTuple}; /// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// ///
@@ -1648,6 +1675,13 @@ pub trait SerializeSeq {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeTuple` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeTuple { pub trait SerializeTuple {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
@@ -1666,6 +1700,8 @@ pub trait SerializeTuple {
/// Returned from `Serializer::serialize_tuple_struct`. /// Returned from `Serializer::serialize_tuple_struct`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct}; /// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// ///
@@ -1684,6 +1720,13 @@ pub trait SerializeTuple {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeTupleStruct` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeTupleStruct { pub trait SerializeTupleStruct {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
@@ -1702,6 +1745,8 @@ pub trait SerializeTupleStruct {
/// Returned from `Serializer::serialize_tuple_variant`. /// Returned from `Serializer::serialize_tuple_variant`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant}; /// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// ///
@@ -1733,6 +1778,13 @@ pub trait SerializeTupleStruct {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeTupleVariant` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeTupleVariant { pub trait SerializeTupleVariant {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
@@ -1751,6 +1803,8 @@ pub trait SerializeTupleVariant {
/// Returned from `Serializer::serialize_map`. /// Returned from `Serializer::serialize_map`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
@@ -1790,6 +1844,13 @@ pub trait SerializeTupleVariant {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeMap` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeMap { pub trait SerializeMap {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
@@ -1853,6 +1914,8 @@ pub trait SerializeMap {
/// Returned from `Serializer::serialize_struct`. /// Returned from `Serializer::serialize_struct`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct}; /// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// ///
@@ -1875,6 +1938,13 @@ pub trait SerializeMap {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeStruct` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeStruct { pub trait SerializeStruct {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
@@ -1904,6 +1974,8 @@ pub trait SerializeStruct {
/// Returned from `Serializer::serialize_struct_variant`. /// Returned from `Serializer::serialize_struct_variant`.
/// ///
/// # Example use
///
/// ```rust /// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant}; /// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// ///
@@ -1928,6 +2000,13 @@ pub trait SerializeStruct {
/// } /// }
/// } /// }
/// ``` /// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeStructVariant` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeStructVariant { pub trait SerializeStructVariant {
/// Must match the `Ok` type of our `Serializer`. /// Must match the `Ok` type of our `Serializer`.
type Ok; type Ok;
+3 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.62" # remember to update html_root_url version = "1.0.65" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -8,8 +8,8 @@ homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
documentation = "https://serde.rs/codegen.html" documentation = "https://serde.rs/codegen.html"
keywords = ["serde", "serialization", "no_std"] keywords = ["serde", "serialization", "no_std"]
readme = "README.md" readme = "crates-io.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[badges] [badges]
travis-ci = { repository = "serde-rs/serde" } travis-ci = { repository = "serde-rs/serde" }
+1
View File
@@ -0,0 +1 @@
../crates-io.md
+1 -1
View File
@@ -22,7 +22,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.62")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.65")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Whitelisted clippy lints
#![cfg_attr( #![cfg_attr(
+2 -2
View File
@@ -8,8 +8,8 @@ homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_derive_internals/" documentation = "https://docs.serde.rs/serde_derive_internals/"
keywords = ["serde", "serialization"] keywords = ["serde", "serialization"]
readme = "README.md" readme = "crates-io.md"
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[lib] [lib]
path = "lib.rs" path = "lib.rs"
+1
View File
@@ -0,0 +1 @@
../crates-io.md
+3 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.62" # remember to update html_root_url version = "1.0.65" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
@@ -8,8 +8,8 @@ homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_test/" documentation = "https://docs.serde.rs/serde_test/"
keywords = ["serde", "serialization"] keywords = ["serde", "serialization"]
readme = "README.md" readme = "crates-io.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"] include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[dependencies] [dependencies]
serde = { version = "1.0.60", path = "../serde" } serde = { version = "1.0.60", path = "../serde" }
+1
View File
@@ -0,0 +1 @@
../crates-io.md
+1 -1
View File
@@ -161,7 +161,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.62")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.65")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))] #![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
+44 -1
View File
@@ -14,7 +14,7 @@ extern crate serde_derive;
extern crate serde; extern crate serde;
use self::serde::de::{self, Unexpected}; use self::serde::de::{self, Unexpected};
use self::serde::{Deserialize, Deserializer, Serialize, Serializer}; use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashMap; use std::collections::{BTreeMap, HashMap};
use std::marker::PhantomData; use std::marker::PhantomData;
extern crate serde_test; extern crate serde_test;
@@ -1683,6 +1683,49 @@ fn test_complex_flatten() {
); );
} }
#[test]
fn test_flatten_map_twice() {
#[derive(Debug, PartialEq, Deserialize)]
struct Outer {
#[serde(flatten)]
first: BTreeMap<String, String>,
#[serde(flatten)]
between: Inner,
#[serde(flatten)]
second: BTreeMap<String, String>,
}
#[derive(Debug, PartialEq, Deserialize)]
struct Inner {
y: String,
}
assert_de_tokens(
&Outer {
first: {
let mut first = BTreeMap::new();
first.insert("x".to_owned(), "X".to_owned());
first.insert("y".to_owned(), "Y".to_owned());
first
},
between: Inner { y: "Y".to_owned() },
second: {
let mut second = BTreeMap::new();
second.insert("x".to_owned(), "X".to_owned());
second
},
},
&[
Token::Map { len: None },
Token::Str("x"),
Token::Str("X"),
Token::Str("y"),
Token::Str("Y"),
Token::MapEnd,
],
);
}
#[test] #[test]
fn test_flatten_unsupported_type() { fn test_flatten_unsupported_type() {
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
+8
View File
@@ -9,6 +9,7 @@
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
use std::cell::RefCell;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::CString; use std::ffi::CString;
use std::mem; use std::mem;
@@ -563,6 +564,13 @@ fn test_cannot_serialize_paths() {
assert_ser_tokens_error(&path_buf, &[], "path contains invalid UTF-8 characters"); assert_ser_tokens_error(&path_buf, &[], "path contains invalid UTF-8 characters");
} }
#[test]
fn test_cannot_serialize_mutably_borrowed_ref_cell() {
let ref_cell = RefCell::new(42);
let _reference = ref_cell.borrow_mut();
assert_ser_tokens_error(&ref_cell, &[], "already mutably borrowed");
}
#[test] #[test]
fn test_enum_skipped() { fn test_enum_skipped() {
assert_ser_tokens_error( assert_ser_tokens_error(