Compare commits

...

36 Commits

Author SHA1 Message Date
David Tolnay ae79451b7a Release 0.9.15 2017-04-23 16:37:43 -07:00
David Tolnay 1a2b3815ef Merge pull request #899 from SimonSapin/z-is-dead-in-0.9-too
Remove usage of unstable core::num::Zero, which was removed upstream.
2017-04-23 16:34:06 -07:00
Simon Sapin 1d6ecf3c2c Remove usage of unstable core::num::Zero, which was removed upstream.
https://github.com/rust-lang/rust/pull/41437

Backport of https://github.com/serde-rs/serde/pull/898 to 0.9.x
2017-04-24 08:25:08 +09:00
David Tolnay d4d2061a2e Release 0.9.14 2017-04-17 07:33:45 -07:00
David Tolnay c202ce13dc Merge pull request #882 from jethrogb/feature/interior_mut_types
Add Serialize/Deserialize for std types that provide interior mutability
2017-04-17 07:32:13 -07:00
Jethro Beekman 1c9478bfa6 Add Serialize/Deserialize for std types that provide interior mutability
Fixes #179
2017-04-16 22:59:17 -07:00
David Tolnay 1232cfd194 Add playground link to readme 2017-04-13 10:19:22 -07:00
David Tolnay 2c49f9aad3 Recommend 'extern crate serde' 2017-04-08 13:53:13 -07:00
David Tolnay 1b763da529 Release 0.9.13 2017-04-05 15:03:37 -07:00
David Tolnay b7d6c5d9f7 Remove no_std special case in forward_to_deserialize 2017-04-05 15:01:55 -07:00
David Tolnay bfabaf3789 Merge pull request #838 from serde-rs/winstr
Deserialize OsString on Windows
2017-04-04 11:33:42 -07:00
David Tolnay cf6c4ab7ec Deserialize OsString on Windows 2017-04-04 11:19:24 -07:00
David Tolnay 8eb50186e0 Merge pull request #831 from serde-rs/derivepath
Use the live serde_derive for serde doc tests
2017-03-30 22:55:33 -07:00
David Tolnay 7d985ff3fd Use the live serde_derive for serde doc tests
This is required as both are updated to Deserialize<'de> together.
2017-03-30 22:45:15 -07:00
David Tolnay 59b3961ad4 Release 0.9.12 2017-03-27 15:45:14 -07:00
David Tolnay dbc9a60c5f Merge pull request #824 from alexcrichton/osstr-osstring
Implement Serialize/Deserialize for OsStr/OsString
2017-03-27 15:39:07 -07:00
Alex Crichton ce687431f3 Implement Serialize/Deserialize for OsStr/OsString
This commit implements the two serde traits for the libstd `OsStr` and
`OsString` types. This came up as a use case during implementing sccache where
we're basically just doing IPC to communicate paths around. Additionally the
`Path` and `PathBuf` implementations have been updated to delegate to the os
string ones.

These types are platform-specific, however, so the serialization/deserialization
isn't trivial. Currently this "fakes" a newtype variant for Unix/Windows to
prevent cross-platform serialization/deserialization. This means if you're doing
IPC within the same OS (e.g. Windows to Windows) then serialization should be
infallible. If you're doing IPC across platforms (e.g.  Unix to Windows) then
using `OsString` is guaranteed to fail as bytes from one OS won't deserialize on
the other (even if they're unicode).
2017-03-27 11:44:50 -07:00
David Tolnay 71ccc5753b Merge pull request #820 from serde-rs/reexport
Re-export derives from serde
2017-03-26 20:37:12 -07:00
David Tolnay 13886435a6 Re-export derives from serde 2017-03-21 16:54:31 -07:00
David Tolnay 08e2182042 UFCS for Option::map and Result::map 2017-03-18 13:31:03 -07:00
David Tolnay d60595cc27 Use format_args! to simplify de::Error 2017-03-18 10:48:47 -07:00
David Tolnay 8c7396c35a Be consistent with UFCS and double underscores 2017-03-18 10:33:22 -07:00
David Tolnay 42b2fd8eec Improve error message parsing from and into 2017-03-18 09:22:44 -07:00
John Baublitz bc946e4fd7 Macro attributes to specify From and Into trait types for structs and enums (#817)
* serde macro support for type conversions through From and Into trait

* Revisions requested by dtolnay

* Additional changes requested by dtolnay
2017-03-18 09:22:27 -07:00
David Tolnay c488cec641 Remove RangeInclusive impl for now
The old impl is inconsistent with the new ops::Range impl.
2017-03-13 11:09:56 -07:00
David Tolnay fcc3c69a49 Range impl is defined when building with std 2017-03-09 12:04:02 -08:00
David Tolnay 350c2e835b Remove duplicate ops::Range serialize impl 2017-03-09 11:57:36 -08:00
David Tolnay a0a031677e Merge pull request #813 from rocallahan/support-range
Implement `Serialize`/`Deserialize` for `Range`
2017-03-09 11:55:21 -08:00
Robert O'Callahan cc0d045f5c Add Deserialize impl for std::ops::Range
Resolves #796
2017-03-10 08:39:34 +13:00
Robert O'Callahan aebe1fddab Add Serialize impl for std::ops::Range 2017-03-10 00:35:04 +13:00
David Tolnay 77ee306b57 Format serde with rustfmt 0.8.0 2017-03-08 21:11:17 -08:00
David Tolnay 6750fdaae1 Merge pull request #811 from jonhoo/deserialize-cstr
Add Deserialize impl for CStr
2017-03-08 21:06:09 -08:00
David Tolnay dd6989d551 Actually run unstable tests 2017-03-08 21:02:15 -08:00
Jon Gjengset 0c2fed49e2 Add Deserialize impl for CStr
Fixes #810
2017-03-08 23:57:26 -05:00
Oliver Schneider a4ee9bd045 Merge pull request #808 from serde-rs/u32
Implement deserialize_enum for U32Deserializer
2017-03-07 18:58:29 +01:00
David Tolnay 6d9397d573 Implement deserialize_enum for U32Deserializer 2017-03-07 09:05:33 -08:00
32 changed files with 1297 additions and 570 deletions
+5
View File
@@ -15,10 +15,15 @@ You may be looking for:
## Serde in action ## Serde in action
<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">
<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png">
</a>
```rust ```rust
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate serde;
extern crate serde_json; extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
+17
View File
@@ -0,0 +1,17 @@
environment:
matrix:
- APPVEYOR_RUST_CHANNEL: stable
- APPVEYOR_RUST_CHANNEL: nightly
install:
# Install rust, x86_64-pc-windows-msvc host
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
- rustup-init.exe -y --default-host x86_64-pc-windows-msvc --default-toolchain %APPVEYOR_RUST_CHANNEL%
- set PATH=C:\msys64\usr\bin;%PATH%;C:\Users\appveyor\.cargo\bin
- rustc -vV
- cargo -vV
build: false
test_script:
- sh -c 'PATH=`rustc --print sysroot`/bin:$PATH ./travis.sh'
+4 -3
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "0.9.11" version = "0.9.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
@@ -17,6 +17,7 @@ travis-ci = { repository = "serde-rs/serde" }
[features] [features]
default = ["std"] default = ["std"]
derive = ["serde_derive"]
std = [] std = []
unstable = [] unstable = []
@@ -28,7 +29,7 @@ unstable-testing = ["unstable", "std"]
playground = ["serde_derive"] playground = ["serde_derive"]
[dependencies] [dependencies]
serde_derive = { version = "0.9", optional = true } serde_derive = { version = "0.9", optional = true, path = "../serde_derive" }
[dev-dependencies] [dev-dependencies]
serde_derive = "0.9" serde_derive = { version = "0.9", path = "../serde_derive" }
+147 -86
View File
@@ -510,9 +510,9 @@ impl<T> Visitor for TaggedContentVisitor<T>
None => Err(de::Error::missing_field(self.tag_name)), None => Err(de::Error::missing_field(self.tag_name)),
Some(tag) => { Some(tag) => {
Ok(TaggedContent { Ok(TaggedContent {
tag: tag, tag: tag,
content: Content::Map(vec), content: Content::Map(vec),
}) })
} }
} }
} }
@@ -604,8 +604,10 @@ impl<E> Deserializer for ContentDeserializer<E>
Ok(value) Ok(value)
} }
Content::Map(v) => { Content::Map(v) => {
let map = v.into_iter() let map = v.into_iter().map(|(k, v)| {
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); (ContentDeserializer::new(k),
ContentDeserializer::new(v))
});
let mut map_visitor = de::value::MapDeserializer::new(map); let mut map_visitor = de::value::MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor)); let value = try!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end()); try!(map_visitor.end());
@@ -632,8 +634,12 @@ impl<E> Deserializer for ContentDeserializer<E>
visitor.visit_newtype_struct(self) visitor.visit_newtype_struct(self)
} }
fn deserialize_enum<V>(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error> fn deserialize_enum<V>(self,
where V: Visitor, _name: &str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value, Self::Error>
where V: Visitor
{ {
let (variant, value) = match self.content { let (variant, value) = match self.content {
Content::Map(value) => { Content::Map(value) => {
@@ -641,12 +647,14 @@ impl<E> Deserializer for ContentDeserializer<E>
let (variant, value) = match iter.next() { let (variant, value) = match iter.next() {
Some(v) => v, Some(v) => v,
None => { None => {
return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key")); return Err(de::Error::invalid_value(de::Unexpected::Map,
&"map with a single key"));
} }
}; };
// enums are encoded in json as maps with a single key:value pair // enums are encoded in json as maps with a single key:value pair
if iter.next().is_some() { if iter.next().is_some() {
return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key")); return Err(de::Error::invalid_value(de::Unexpected::Map,
&"map with a single key"));
} }
(variant, Some(value)) (variant, Some(value))
} }
@@ -657,10 +665,10 @@ impl<E> Deserializer for ContentDeserializer<E>
}; };
visitor.visit_enum(EnumDeserializer { visitor.visit_enum(EnumDeserializer {
variant: variant, variant: variant,
value: value, value: value,
err: PhantomData, err: PhantomData,
}) })
} }
forward_to_deserialize! { forward_to_deserialize! {
@@ -680,30 +688,43 @@ impl<E> ContentDeserializer<E> {
} }
} }
struct EnumDeserializer<E> where E: de::Error { struct EnumDeserializer<E>
where E: de::Error
{
variant: Content, variant: Content,
value: Option<Content>, value: Option<Content>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<E> de::EnumVisitor for EnumDeserializer<E> where E: de::Error { impl<E> de::EnumVisitor for EnumDeserializer<E>
where E: de::Error
{
type Error = E; type Error = E;
type Variant = VariantDeserializer<Self::Error>; type Variant = VariantDeserializer<Self::Error>;
fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer<E>), Self::Error> fn visit_variant_seed<V>(self,
where V: de::DeserializeSeed, seed: V)
-> Result<(V::Value, VariantDeserializer<E>), Self::Error>
where V: de::DeserializeSeed
{ {
let visitor = VariantDeserializer { value: self.value, err: PhantomData, }; let visitor = VariantDeserializer {
value: self.value,
err: PhantomData,
};
seed.deserialize(ContentDeserializer::new(self.variant)).map(|v| (v, visitor)) seed.deserialize(ContentDeserializer::new(self.variant)).map(|v| (v, visitor))
} }
} }
struct VariantDeserializer<E> where E: de::Error { struct VariantDeserializer<E>
where E: de::Error
{
value: Option<Content>, value: Option<Content>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<E> de::VariantVisitor for VariantDeserializer<E> where E: de::Error { impl<E> de::VariantVisitor for VariantDeserializer<E>
where E: de::Error
{
type Error = E; type Error = E;
fn visit_unit(self) -> Result<(), E> { fn visit_unit(self) -> Result<(), E> {
@@ -722,11 +743,7 @@ impl<E> de::VariantVisitor for VariantDeserializer<E> where E: de::Error {
} }
} }
fn visit_tuple<V>( fn visit_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
self,
_len: usize,
visitor: V
) -> Result<V::Value, Self::Error>
where V: de::Visitor where V: de::Visitor
{ {
match self.value { match self.value {
@@ -734,15 +751,14 @@ impl<E> de::VariantVisitor for VariantDeserializer<E> where E: de::Error {
de::Deserializer::deserialize(SeqDeserializer::new(v), visitor) de::Deserializer::deserialize(SeqDeserializer::new(v), visitor)
} }
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")),
None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")) None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")),
} }
} }
fn visit_struct<V>( fn visit_struct<V>(self,
self, _fields: &'static [&'static str],
_fields: &'static [&'static str], visitor: V)
visitor: V -> Result<V::Value, Self::Error>
) -> Result<V::Value, Self::Error>
where V: de::Visitor where V: de::Visitor
{ {
match self.value { match self.value {
@@ -750,17 +766,21 @@ impl<E> de::VariantVisitor for VariantDeserializer<E> where E: de::Error {
de::Deserializer::deserialize(MapDeserializer::new(v), visitor) de::Deserializer::deserialize(MapDeserializer::new(v), visitor)
} }
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")) _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")),
} }
} }
} }
struct SeqDeserializer<E> where E: de::Error { struct SeqDeserializer<E>
where E: de::Error
{
iter: <Vec<Content> as IntoIterator>::IntoIter, iter: <Vec<Content> as IntoIterator>::IntoIter,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<E> SeqDeserializer<E> where E: de::Error { impl<E> SeqDeserializer<E>
where E: de::Error
{
fn new(vec: Vec<Content>) -> Self { fn new(vec: Vec<Content>) -> Self {
SeqDeserializer { SeqDeserializer {
iter: vec.into_iter(), iter: vec.into_iter(),
@@ -769,12 +789,14 @@ impl<E> SeqDeserializer<E> where E: de::Error {
} }
} }
impl<E> de::Deserializer for SeqDeserializer<E> where E: de::Error { impl<E> de::Deserializer for SeqDeserializer<E>
where E: de::Error
{
type Error = E; type Error = E;
#[inline] #[inline]
fn deserialize<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor
{ {
let len = self.iter.len(); let len = self.iter.len();
if len == 0 { if len == 0 {
@@ -797,11 +819,13 @@ impl<E> de::Deserializer for SeqDeserializer<E> where E: de::Error {
} }
} }
impl<E> de::SeqVisitor for SeqDeserializer<E> where E: de::Error { impl<E> de::SeqVisitor for SeqDeserializer<E>
where E: de::Error
{
type Error = E; type Error = E;
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed, where T: de::DeserializeSeed
{ {
match self.iter.next() { match self.iter.next() {
Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some),
@@ -814,13 +838,17 @@ impl<E> de::SeqVisitor for SeqDeserializer<E> where E: de::Error {
} }
} }
struct MapDeserializer<E> where E: de::Error { struct MapDeserializer<E>
where E: de::Error
{
iter: <Vec<(Content, Content)> as IntoIterator>::IntoIter, iter: <Vec<(Content, Content)> as IntoIterator>::IntoIter,
value: Option<Content>, value: Option<Content>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<E> MapDeserializer<E> where E: de::Error { impl<E> MapDeserializer<E>
where E: de::Error
{
fn new(map: Vec<(Content, Content)>) -> Self { fn new(map: Vec<(Content, Content)>) -> Self {
MapDeserializer { MapDeserializer {
iter: map.into_iter(), iter: map.into_iter(),
@@ -830,11 +858,13 @@ impl<E> MapDeserializer<E> where E: de::Error {
} }
} }
impl<E> de::MapVisitor for MapDeserializer<E> where E: de::Error { impl<E> de::MapVisitor for MapDeserializer<E>
where E: de::Error
{
type Error = E; type Error = E;
fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed, where T: de::DeserializeSeed
{ {
match self.iter.next() { match self.iter.next() {
Some((key, value)) => { Some((key, value)) => {
@@ -846,7 +876,7 @@ impl<E> de::MapVisitor for MapDeserializer<E> where E: de::Error {
} }
fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where T: de::DeserializeSeed, where T: de::DeserializeSeed
{ {
match self.value.take() { match self.value.take() {
Some(value) => seed.deserialize(ContentDeserializer::new(value)), Some(value) => seed.deserialize(ContentDeserializer::new(value)),
@@ -859,12 +889,14 @@ impl<E> de::MapVisitor for MapDeserializer<E> where E: de::Error {
} }
} }
impl<E> de::Deserializer for MapDeserializer<E> where E: de::Error { impl<E> de::Deserializer for MapDeserializer<E>
where E: de::Error
{
type Error = E; type Error = E;
#[inline] #[inline]
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor
{ {
visitor.visit_map(self) visitor.visit_map(self)
} }
@@ -920,8 +952,9 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E>
} }
Content::Map(ref v) => { Content::Map(ref v) => {
let map = v.into_iter().map(|&(ref k, ref v)| { let map = v.into_iter().map(|&(ref k, ref v)| {
(ContentRefDeserializer::new(k), ContentRefDeserializer::new(v)) (ContentRefDeserializer::new(k),
}); ContentRefDeserializer::new(v))
});
let mut map_visitor = de::value::MapDeserializer::new(map); let mut map_visitor = de::value::MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor)); let value = try!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end()); try!(map_visitor.end());
@@ -948,8 +981,12 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E>
visitor.visit_newtype_struct(self) visitor.visit_newtype_struct(self)
} }
fn deserialize_enum<V>(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result<V::Value, Self::Error> fn deserialize_enum<V>(self,
where V: Visitor, _name: &str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value, Self::Error>
where V: Visitor
{ {
let (variant, value) = match *self.content { let (variant, value) = match *self.content {
Content::Map(ref value) => { Content::Map(ref value) => {
@@ -957,12 +994,14 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E>
let &(ref variant, ref value) = match iter.next() { let &(ref variant, ref value) = match iter.next() {
Some(v) => v, Some(v) => v,
None => { None => {
return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key")); return Err(de::Error::invalid_value(de::Unexpected::Map,
&"map with a single key"));
} }
}; };
// enums are encoded in json as maps with a single key:value pair // enums are encoded in json as maps with a single key:value pair
if iter.next().is_some() { if iter.next().is_some() {
return Err(de::Error::invalid_value(de::Unexpected::Map, &"map with a single key")); return Err(de::Error::invalid_value(de::Unexpected::Map,
&"map with a single key"));
} }
(variant, Some(value)) (variant, Some(value))
} }
@@ -973,10 +1012,10 @@ impl<'a, E> Deserializer for ContentRefDeserializer<'a, E>
}; };
visitor.visit_enum(EnumRefDeserializer { visitor.visit_enum(EnumRefDeserializer {
variant: variant, variant: variant,
value: value, value: value,
err: PhantomData, err: PhantomData,
}) })
} }
forward_to_deserialize! { forward_to_deserialize! {
@@ -996,30 +1035,41 @@ impl<'a, E> ContentRefDeserializer<'a, E> {
} }
} }
struct EnumRefDeserializer<'a, E> where E: de::Error { struct EnumRefDeserializer<'a, E>
where E: de::Error
{
variant: &'a Content, variant: &'a Content,
value: Option<&'a Content>, value: Option<&'a Content>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'a, E> de::EnumVisitor for EnumRefDeserializer<'a, E> where E: de::Error { impl<'a, E> de::EnumVisitor for EnumRefDeserializer<'a, E>
where E: de::Error
{
type Error = E; type Error = E;
type Variant = VariantRefDeserializer<'a, Self::Error>; type Variant = VariantRefDeserializer<'a, Self::Error>;
fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> fn visit_variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where V: de::DeserializeSeed, where V: de::DeserializeSeed
{ {
let visitor = VariantRefDeserializer { value: self.value, err: PhantomData, }; let visitor = VariantRefDeserializer {
value: self.value,
err: PhantomData,
};
seed.deserialize(ContentRefDeserializer::new(self.variant)).map(|v| (v, visitor)) seed.deserialize(ContentRefDeserializer::new(self.variant)).map(|v| (v, visitor))
} }
} }
struct VariantRefDeserializer<'a, E> where E: de::Error { struct VariantRefDeserializer<'a, E>
where E: de::Error
{
value: Option<&'a Content>, value: Option<&'a Content>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> where E: de::Error { impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E>
where E: de::Error
{
type Error = E; type Error = E;
fn visit_unit(self) -> Result<(), E> { fn visit_unit(self) -> Result<(), E> {
@@ -1038,11 +1088,7 @@ impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> where E: de::Er
} }
} }
fn visit_tuple<V>( fn visit_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
self,
_len: usize,
visitor: V
) -> Result<V::Value, Self::Error>
where V: de::Visitor where V: de::Visitor
{ {
match self.value { match self.value {
@@ -1050,15 +1096,14 @@ impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> where E: de::Er
de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor) de::Deserializer::deserialize(SeqRefDeserializer::new(v), visitor)
} }
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")),
None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")) None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"tuple variant")),
} }
} }
fn visit_struct<V>( fn visit_struct<V>(self,
self, _fields: &'static [&'static str],
_fields: &'static [&'static str], visitor: V)
visitor: V -> Result<V::Value, Self::Error>
) -> Result<V::Value, Self::Error>
where V: de::Visitor where V: de::Visitor
{ {
match self.value { match self.value {
@@ -1066,17 +1111,21 @@ impl<'a, E> de::VariantVisitor for VariantRefDeserializer<'a, E> where E: de::Er
de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor) de::Deserializer::deserialize(MapRefDeserializer::new(v), visitor)
} }
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")), Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant")),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")) _ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant")),
} }
} }
} }
struct SeqRefDeserializer<'a, E> where E: de::Error { struct SeqRefDeserializer<'a, E>
where E: de::Error
{
iter: <&'a [Content] as IntoIterator>::IntoIter, iter: <&'a [Content] as IntoIterator>::IntoIter,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'a, E> SeqRefDeserializer<'a, E> where E: de::Error { impl<'a, E> SeqRefDeserializer<'a, E>
where E: de::Error
{
fn new(vec: &'a [Content]) -> Self { fn new(vec: &'a [Content]) -> Self {
SeqRefDeserializer { SeqRefDeserializer {
iter: vec.into_iter(), iter: vec.into_iter(),
@@ -1085,12 +1134,14 @@ impl<'a, E> SeqRefDeserializer<'a, E> where E: de::Error {
} }
} }
impl<'a, E> de::Deserializer for SeqRefDeserializer<'a, E> where E: de::Error { impl<'a, E> de::Deserializer for SeqRefDeserializer<'a, E>
where E: de::Error
{
type Error = E; type Error = E;
#[inline] #[inline]
fn deserialize<V>(mut self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor
{ {
let len = self.iter.len(); let len = self.iter.len();
if len == 0 { if len == 0 {
@@ -1113,11 +1164,13 @@ impl<'a, E> de::Deserializer for SeqRefDeserializer<'a, E> where E: de::Error {
} }
} }
impl<'a, E> de::SeqVisitor for SeqRefDeserializer<'a, E> where E: de::Error { impl<'a, E> de::SeqVisitor for SeqRefDeserializer<'a, E>
where E: de::Error
{
type Error = E; type Error = E;
fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> fn visit_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed, where T: de::DeserializeSeed
{ {
match self.iter.next() { match self.iter.next() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some), Some(value) => seed.deserialize(ContentRefDeserializer::new(value)).map(Some),
@@ -1130,13 +1183,17 @@ impl<'a, E> de::SeqVisitor for SeqRefDeserializer<'a, E> where E: de::Error {
} }
} }
struct MapRefDeserializer<'a, E> where E: de::Error { struct MapRefDeserializer<'a, E>
where E: de::Error
{
iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter, iter: <&'a [(Content, Content)] as IntoIterator>::IntoIter,
value: Option<&'a Content>, value: Option<&'a Content>,
err: PhantomData<E>, err: PhantomData<E>,
} }
impl<'a, E> MapRefDeserializer<'a, E> where E: de::Error { impl<'a, E> MapRefDeserializer<'a, E>
where E: de::Error
{
fn new(map: &'a [(Content, Content)]) -> Self { fn new(map: &'a [(Content, Content)]) -> Self {
MapRefDeserializer { MapRefDeserializer {
iter: map.into_iter(), iter: map.into_iter(),
@@ -1146,11 +1203,13 @@ impl<'a, E> MapRefDeserializer<'a, E> where E: de::Error {
} }
} }
impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> where E: de::Error { impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E>
where E: de::Error
{
type Error = E; type Error = E;
fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> fn visit_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where T: de::DeserializeSeed, where T: de::DeserializeSeed
{ {
match self.iter.next() { match self.iter.next() {
Some(&(ref key, ref value)) => { Some(&(ref key, ref value)) => {
@@ -1162,7 +1221,7 @@ impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> where E: de::Error {
} }
fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error> fn visit_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where T: de::DeserializeSeed, where T: de::DeserializeSeed
{ {
match self.value.take() { match self.value.take() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)), Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
@@ -1175,12 +1234,14 @@ impl<'a, E> de::MapVisitor for MapRefDeserializer<'a, E> where E: de::Error {
} }
} }
impl<'a, E> de::Deserializer for MapRefDeserializer<'a, E> where E: de::Error { impl<'a, E> de::Deserializer for MapRefDeserializer<'a, E>
where E: de::Error
{
type Error = E; type Error = E;
#[inline] #[inline]
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor, where V: de::Visitor
{ {
visitor.visit_map(self) visitor.visit_map(self)
} }
+326 -11
View File
@@ -20,13 +20,19 @@ use core::fmt;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use core::hash::{Hash, BuildHasher}; use core::hash::{Hash, BuildHasher};
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(all(feature="unstable"))]
use core::mem;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::net; use std::net;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::path; use std::path;
#[cfg(all(feature="unstable"))]
use core::slice;
use core::str; use core::str;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::ffi::CString; use std::ffi::{CString, OsString};
#[cfg(all(feature = "std", feature="unstable"))]
use std::ffi::CStr;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::rc::Rc; use std::rc::Rc;
@@ -41,15 +47,19 @@ use alloc::arc::Arc;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box; use alloc::boxed::Box;
use core::cell::{Cell, RefCell};
#[cfg(feature = "std")]
use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::time::Duration; use std::time::Duration;
#[cfg(feature = "unstable")] #[cfg(feature = "std")]
use core::nonzero::{NonZero, Zeroable}; use std;
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[allow(deprecated)] // required for impl Deserialize for NonZero<T> use core::nonzero::{NonZero, Zeroable};
use core::num::Zero;
use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, Unexpected, use de::{Deserialize, Deserializer, EnumVisitor, Error, MapVisitor, SeqVisitor, Unexpected,
VariantVisitor, Visitor}; VariantVisitor, Visitor};
@@ -300,6 +310,16 @@ impl Deserialize for String {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "std", feature="unstable"))]
impl Deserialize for Box<CStr> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer
{
let s = try!(CString::deserialize(deserializer));
Ok(s.into_boxed_c_str())
}
}
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl Deserialize for CString { impl Deserialize for CString {
fn deserialize<D>(deserializer: D) -> Result<CString, D::Error> fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
@@ -895,6 +915,7 @@ impl Visitor for PathBufVisitor {
} }
} }
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl Deserialize for path::PathBuf { impl Deserialize for path::PathBuf {
fn deserialize<D>(deserializer: D) -> Result<path::PathBuf, D::Error> fn deserialize<D>(deserializer: D) -> Result<path::PathBuf, D::Error>
@@ -906,6 +927,126 @@ impl Deserialize for path::PathBuf {
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "std", any(unix, windows)))]
enum OsStringKind {
Unix,
Windows,
}
#[cfg(all(feature = "std", any(unix, windows)))]
static OSSTR_VARIANTS: &'static [&'static str] = &["Unix", "Windows"];
#[cfg(all(feature = "std", any(unix, windows)))]
impl Deserialize for OsStringKind {
fn deserialize<D>(deserializer: D) -> Result<OsStringKind, D::Error>
where D: Deserializer
{
struct KindVisitor;
impl Visitor for KindVisitor {
type Value = OsStringKind;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`Unix` or `Windows`")
}
fn visit_u32<E>(self, value: u32) -> Result<OsStringKind, E>
where E: Error,
{
match value {
0 => Ok(OsStringKind::Unix),
1 => Ok(OsStringKind::Windows),
_ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self))
}
}
fn visit_str<E>(self, value: &str) -> Result<OsStringKind, E>
where E: Error,
{
match value {
"Unix" => Ok(OsStringKind::Unix),
"Windows" => Ok(OsStringKind::Windows),
_ => Err(Error::unknown_variant(value, OSSTR_VARIANTS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<OsStringKind, E>
where E: Error,
{
match value {
b"Unix" => Ok(OsStringKind::Unix),
b"Windows" => Ok(OsStringKind::Windows),
_ => {
match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_variant(value, OSSTR_VARIANTS)),
Err(_) => {
Err(Error::invalid_value(Unexpected::Bytes(value), &self))
}
}
}
}
}
}
deserializer.deserialize(KindVisitor)
}
}
#[cfg(all(feature = "std", any(unix, windows)))]
struct OsStringVisitor;
#[cfg(all(feature = "std", any(unix, windows)))]
impl Visitor for OsStringVisitor {
type Value = OsString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("os string")
}
#[cfg(unix)]
fn visit_enum<V>(self, visitor: V) -> Result<OsString, V::Error>
where V: EnumVisitor,
{
use std::os::unix::ffi::OsStringExt;
match try!(visitor.visit_variant()) {
(OsStringKind::Unix, variant) => {
variant.visit_newtype().map(OsString::from_vec)
}
(OsStringKind::Windows, _) => {
Err(Error::custom("cannot deserialize Windows OS string on Unix"))
}
}
}
#[cfg(windows)]
fn visit_enum<V>(self, visitor: V) -> Result<OsString, V::Error>
where V: EnumVisitor,
{
use std::os::windows::ffi::OsStringExt;
match try!(visitor.visit_variant()) {
(OsStringKind::Windows, variant) => {
variant.visit_newtype::<Vec<u16>>().map(|vec| OsString::from_wide(&vec))
}
(OsStringKind::Unix, _) => {
Err(Error::custom("cannot deserialize Unix OS string on Windows"))
}
}
}
}
#[cfg(all(feature = "std", any(unix, windows)))]
impl Deserialize for OsString {
fn deserialize<D>(deserializer: D) -> Result<OsString, D::Error>
where D: Deserializer
{
deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor)
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<T: Deserialize> Deserialize for Box<T> { impl<T: Deserialize> Deserialize for Box<T> {
fn deserialize<D>(deserializer: D) -> Result<Box<T>, D::Error> fn deserialize<D>(deserializer: D) -> Result<Box<T>, D::Error>
@@ -970,6 +1111,44 @@ impl<'a, T: ?Sized> Deserialize for Cow<'a, T>
} }
} }
impl<T: Deserialize + Copy> Deserialize for Cell<T> {
fn deserialize<D>(deserializer: D) -> Result<Cell<T>, D::Error>
where D: Deserializer
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Cell::new(val))
}
}
impl<T: Deserialize> Deserialize for RefCell<T> {
fn deserialize<D>(deserializer: D) -> Result<RefCell<T>, D::Error>
where D: Deserializer
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(RefCell::new(val))
}
}
#[cfg(feature = "std")]
impl<T: Deserialize> Deserialize for Mutex<T> {
fn deserialize<D>(deserializer: D) -> Result<Mutex<T>, D::Error>
where D: Deserializer
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(Mutex::new(val))
}
}
#[cfg(feature = "std")]
impl<T: Deserialize> Deserialize for RwLock<T> {
fn deserialize<D>(deserializer: D) -> Result<RwLock<T>, D::Error>
where D: Deserializer
{
let val = try!(Deserialize::deserialize(deserializer));
Ok(RwLock::new(val))
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// This is a cleaned-up version of the impl generated by: // This is a cleaned-up version of the impl generated by:
@@ -1096,21 +1275,157 @@ impl Deserialize for Duration {
} }
} }
///////////////////////////////////////////////////////////////////////////////
// Similar to:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct Range {
// start: u64,
// end: u32,
// }
#[cfg(feature = "std")]
impl<Idx: Deserialize> Deserialize for std::ops::Range<Idx> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer
{
enum Field {
Start,
End,
};
impl Deserialize for Field {
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
where D: Deserializer
{
struct FieldVisitor;
impl Visitor for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start` or `end`")
}
fn visit_str<E>(self, value: &str) -> Result<Field, E>
where E: Error
{
match value {
"start" => Ok(Field::Start),
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
where E: Error
{
match value {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = String::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
}
}
deserializer.deserialize_struct_field(FieldVisitor)
}
}
struct RangeVisitor<Idx> {
phantom: PhantomData<Idx>,
}
impl<Idx: Deserialize> Visitor for RangeVisitor<Idx> {
type Value = std::ops::Range<Idx>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Range")
}
fn visit_seq<V>(self, mut visitor: V) -> Result<std::ops::Range<Idx>, V::Error>
where V: SeqVisitor
{
let start: Idx = match try!(visitor.visit()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
let end: Idx = match try!(visitor.visit()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(start..end)
}
fn visit_map<V>(self, mut visitor: V) -> Result<std::ops::Range<Idx>, V::Error>
where V: MapVisitor
{
let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None;
while let Some(key) = try!(visitor.visit_key::<Field>()) {
match key {
Field::Start => {
if start.is_some() {
return Err(<V::Error as Error>::duplicate_field("start"));
}
start = Some(try!(visitor.visit_value()));
}
Field::End => {
if end.is_some() {
return Err(<V::Error as Error>::duplicate_field("end"));
}
end = Some(try!(visitor.visit_value()));
}
}
}
let start = match start {
Some(start) => start,
None => return Err(<V::Error as Error>::missing_field("start")),
};
let end = match end {
Some(end) => end,
None => return Err(<V::Error as Error>::missing_field("end")),
};
Ok(start..end)
}
}
const FIELDS: &'static [&'static str] = &["start", "end"];
deserializer.deserialize_struct("Range", FIELDS, RangeVisitor { phantom: PhantomData })
}
}
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[allow(deprecated)] // num::Zero is deprecated but there is no replacement
impl<T> Deserialize for NonZero<T> impl<T> Deserialize for NonZero<T>
where T: Deserialize + PartialEq + Zeroable + Zero where T: Deserialize + Zeroable
{ {
fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error> fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
where D: Deserializer where D: Deserializer
{ {
let value = try!(Deserialize::deserialize(deserializer)); let value = try!(Deserialize::deserialize(deserializer));
if value == Zero::zero() { unsafe {
return Err(Error::custom("expected a non-zero value")); let ptr = &value as *const T as *const u8;
} if slice::from_raw_parts(ptr, mem::size_of::<T>()).iter().all(|&b| b == 0) {
unsafe { Ok(NonZero::new(value)) } return Err(Error::custom("expected a non-zero value"));
}
// Waiting for a safe way to construct NonZero<T>:
// https://github.com/rust-lang/rust/issues/27730#issuecomment-269726075
Ok(NonZero::new(value))
}
} }
} }
+23 -99
View File
@@ -64,6 +64,10 @@
//! - Rc\<T\> //! - Rc\<T\>
//! - Arc\<T\> //! - Arc\<T\>
//! - Cow\<'a, T\> //! - Cow\<'a, T\>
//! - Cell\<T\>
//! - RefCell\<T\>
//! - Mutex\<T\>
//! - RwLock\<T\>
//! - **Collection types**: //! - **Collection types**:
//! - BTreeMap\<K, V\> //! - BTreeMap\<K, V\>
//! - BTreeSet\<T\> //! - BTreeSet\<T\>
@@ -172,19 +176,7 @@ pub trait Error: Sized + error::Error {
/// containing an integer, the unexpected type is the integer and the /// containing an integer, the unexpected type is the integer and the
/// expected type is the string. /// expected type is the string.
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self { fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
struct InvalidType<'a> { Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
unexp: Unexpected<'a>,
exp: &'a Expected,
}
impl<'a> Display for InvalidType<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "invalid type: {}, expected {}", self.unexp, self.exp)
}
}
Error::custom(InvalidType {
unexp: unexp,
exp: exp,
})
} }
/// Raised when a `Deserialize` receives a value of the right type but that /// Raised when a `Deserialize` receives a value of the right type but that
@@ -201,19 +193,7 @@ pub trait Error: Sized + error::Error {
/// that is not valid UTF-8, the unexpected value is the bytes and the /// that is not valid UTF-8, the unexpected value is the bytes and the
/// expected value is a string. /// expected value is a string.
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self { fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
struct InvalidValue<'a> { Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
unexp: Unexpected<'a>,
exp: &'a Expected,
}
impl<'a> Display for InvalidValue<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "invalid value: {}, expected {}", self.unexp, self.exp)
}
}
Error::custom(InvalidValue {
unexp: unexp,
exp: exp,
})
} }
/// Raised when deserializing a sequence or map and the input data contains /// Raised when deserializing a sequence or map and the input data contains
@@ -226,102 +206,46 @@ pub trait Error: Sized + error::Error {
/// expected. For example `exp` might say that a tuple of size 6 was /// expected. For example `exp` might say that a tuple of size 6 was
/// expected. /// expected.
fn invalid_length(len: usize, exp: &Expected) -> Self { fn invalid_length(len: usize, exp: &Expected) -> Self {
struct InvalidLength<'a> { Error::custom(format_args!("invalid length {}, expected {}", len, exp))
len: usize,
exp: &'a Expected,
}
impl<'a> Display for InvalidLength<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "invalid length {}, expected {}", self.len, self.exp)
}
}
Error::custom(InvalidLength {
len: len,
exp: exp,
})
} }
/// Raised when a `Deserialize` enum type received a variant with an /// Raised when a `Deserialize` enum type received a variant with an
/// unrecognized name. /// unrecognized name.
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
struct UnknownVariant<'a> { if expected.is_empty() {
variant: &'a str, Error::custom(format_args!("unknown variant `{}`, there are no variants",
expected: &'static [&'static str], variant))
} else {
Error::custom(format_args!("unknown variant `{}`, expected {}",
variant,
OneOf { names: expected }))
} }
impl<'a> Display for UnknownVariant<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.expected.is_empty() {
write!(formatter,
"unknown variant `{}`, there are no variants",
self.variant)
} else {
write!(formatter,
"unknown variant `{}`, expected {}",
self.variant,
OneOf { names: self.expected })
}
}
}
Error::custom(UnknownVariant {
variant: variant,
expected: expected,
})
} }
/// Raised when a `Deserialize` struct type received a field with an /// Raised when a `Deserialize` struct type received a field with an
/// unrecognized name. /// unrecognized name.
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
struct UnknownField<'a> { if expected.is_empty() {
field: &'a str, Error::custom(format_args!("unknown field `{}`, there are no fields",
expected: &'static [&'static str], field))
} else {
Error::custom(format_args!("unknown field `{}`, expected {}",
field,
OneOf { names: expected }))
} }
impl<'a> Display for UnknownField<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
if self.expected.is_empty() {
write!(formatter,
"unknown field `{}`, there are no fields",
self.field)
} else {
write!(formatter,
"unknown field `{}`, expected {}",
self.field,
OneOf { names: self.expected })
}
}
}
Error::custom(UnknownField {
field: field,
expected: expected,
})
} }
/// Raised when a `Deserialize` struct type expected to receive a required /// Raised when a `Deserialize` struct type expected to receive a required
/// field with a particular name but that field was not present in the /// field with a particular name but that field was not present in the
/// input. /// input.
fn missing_field(field: &'static str) -> Self { fn missing_field(field: &'static str) -> Self {
struct MissingField { Error::custom(format_args!("missing field `{}`", field))
field: &'static str,
}
impl Display for MissingField {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "missing field `{}`", self.field)
}
}
Error::custom(MissingField { field: field })
} }
/// Raised when a `Deserialize` struct type received more than one of the /// Raised when a `Deserialize` struct type received more than one of the
/// same field. /// same field.
fn duplicate_field(field: &'static str) -> Self { fn duplicate_field(field: &'static str) -> Self {
struct DuplicateField { Error::custom(format_args!("duplicate field `{}`", field))
field: &'static str,
}
impl Display for DuplicateField {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "duplicate field `{}`", self.field)
}
}
Error::custom(DuplicateField { field: field })
} }
} }
+60 -1
View File
@@ -183,13 +183,72 @@ primitive_deserializer!(i64, I64Deserializer, visit_i64);
primitive_deserializer!(isize, IsizeDeserializer, visit_i64 as i64); primitive_deserializer!(isize, IsizeDeserializer, visit_i64 as i64);
primitive_deserializer!(u8, U8Deserializer, visit_u8); primitive_deserializer!(u8, U8Deserializer, visit_u8);
primitive_deserializer!(u16, U16Deserializer, visit_u16); primitive_deserializer!(u16, U16Deserializer, visit_u16);
primitive_deserializer!(u32, U32Deserializer, visit_u32);
primitive_deserializer!(u64, U64Deserializer, visit_u64); primitive_deserializer!(u64, U64Deserializer, visit_u64);
primitive_deserializer!(usize, UsizeDeserializer, visit_u64 as u64); primitive_deserializer!(usize, UsizeDeserializer, visit_u64 as u64);
primitive_deserializer!(f32, F32Deserializer, visit_f32); primitive_deserializer!(f32, F32Deserializer, visit_f32);
primitive_deserializer!(f64, F64Deserializer, visit_f64); primitive_deserializer!(f64, F64Deserializer, visit_f64);
primitive_deserializer!(char, CharDeserializer, visit_char); primitive_deserializer!(char, CharDeserializer, visit_char);
/// A helper deserializer that deserializes a number.
pub struct U32Deserializer<E> {
value: u32,
marker: PhantomData<E>,
}
impl<E> ValueDeserializer<E> for u32
where E: de::Error
{
type Deserializer = U32Deserializer<E>;
fn into_deserializer(self) -> U32Deserializer<E> {
U32Deserializer {
value: self,
marker: PhantomData,
}
}
}
impl<E> de::Deserializer for U32Deserializer<E>
where E: de::Error
{
type Error = E;
forward_to_deserialize! {
bool u8 u16 u32 u64 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 ignored_any byte_buf
}
fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor
{
visitor.visit_u32(self.value)
}
fn deserialize_enum<V>(self,
_name: &str,
_variants: &'static [&'static str],
visitor: V)
-> Result<V::Value, Self::Error>
where V: de::Visitor
{
visitor.visit_enum(self)
}
}
impl<E> de::EnumVisitor for U32Deserializer<E>
where E: de::Error
{
type Error = E;
type Variant = private::UnitOnly<E>;
fn visit_variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where T: de::DeserializeSeed
{
seed.deserialize(self).map(private::unit_only)
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// A helper deserializer that deserializes a `&str`. /// A helper deserializer that deserializes a `&str`.
+2
View File
@@ -6,6 +6,8 @@ use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))] #[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow; use collections::borrow::Cow;
pub use core::clone::Clone;
pub use core::convert::{From, Into};
pub use core::default::Default; pub use core::default::Default;
pub use core::fmt; pub use core::fmt;
pub use core::marker::PhantomData; pub use core::marker::PhantomData;
+50 -2
View File
@@ -61,7 +61,7 @@
#![doc(html_root_url="https://docs.serde.rs")] #![doc(html_root_url="https://docs.serde.rs")]
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "unstable", feature(inclusive_range, nonzero, specialization, zero_one))] #![cfg_attr(feature = "unstable", feature(nonzero, specialization, into_boxed_c_str))]
#![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))] #![cfg_attr(feature = "collections", feature(collections))]
#![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))] #![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))]
@@ -79,7 +79,8 @@ extern crate core as actual_core;
#[cfg(feature = "std")] #[cfg(feature = "std")]
mod core { mod core {
pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize, pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize,
usize, f32, f64, char, str, num, slice, iter, cell, default, result, option}; usize, f32, f64, char, str, num, slice, iter, cell, default, result, option,
clone, convert};
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
pub use actual_core::nonzero; pub use actual_core::nonzero;
} }
@@ -105,3 +106,50 @@ mod utils;
// Generated code uses these to support no_std. Not public API. // Generated code uses these to support no_std. Not public API.
#[doc(hidden)] #[doc(hidden)]
pub mod export; pub mod export;
// Re-export #[derive(Serialize, Deserialize)].
//
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
// [features]
// serde-impls = ["serde", "serde_derive"]
//
// [dependencies]
// serde = { version = "1.0", optional = true }
// serde_derive = { version = "1.0", optional = true }
//
// # Used like this:
// # #[cfg(feature = "serde-impls")]
// # #[macro_use]
// # extern crate serde_derive;
// #
// # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
// # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
// [dependencies]
// serde = { version = "1.0", optional = true, features = ["derive"] }
//
// # Used like this:
// # #[cfg(feature = "serde")]
// # #[macro_use]
// # extern crate serde;
// #
// # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
// # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
+1 -16
View File
@@ -1,24 +1,9 @@
#[cfg(feature = "std")]
#[doc(hidden)] #[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! forward_to_deserialize_method { macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => { ($func:ident($($arg:ty),*)) => {
#[inline] #[inline]
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error> fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> $crate::export::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor where __V: $crate::de::Visitor
{ {
self.deserialize(visitor) self.deserialize(visitor)
+62 -90
View File
@@ -33,10 +33,7 @@ impl<M> ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue<M>
type Ok = M::Ok; type Ok = M::Ok;
type Error = M::Error; type Error = M::Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), M::Error> {
value: &T)
-> Result<(), M::Error>
{
let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
@@ -73,8 +70,7 @@ impl<M> ser::SerializeStructVariant for SerializeStructVariantAsMapValue<M>
fn serialize_field<T: ?Sized + Serialize>(&mut self, fn serialize_field<T: ?Sized + Serialize>(&mut self,
key: &'static str, key: &'static str,
value: &T) value: &T)
-> Result<(), M::Error> -> Result<(), M::Error> {
{
let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push((key, value)); self.fields.push((key, value));
Ok(()) Ok(())
@@ -151,7 +147,9 @@ impl Serialize for Content {
Content::UnitStruct(n) => serializer.serialize_unit_struct(n), Content::UnitStruct(n) => serializer.serialize_unit_struct(n),
Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v), Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v),
Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c), Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c),
Content::NewtypeVariant(n, i, v, ref c) => serializer.serialize_newtype_variant(n, i, v, &**c), Content::NewtypeVariant(n, i, v, ref c) => {
serializer.serialize_newtype_variant(n, i, v, &**c)
}
Content::Seq(ref elements) => elements.serialize(serializer), Content::Seq(ref elements) => elements.serialize(serializer),
Content::SeqFixedSize(ref elements) => { Content::SeqFixedSize(ref elements) => {
use ser::SerializeSeq; use ser::SerializeSeq;
@@ -219,9 +217,7 @@ struct ContentSerializer<E> {
impl<E> ContentSerializer<E> { impl<E> ContentSerializer<E> {
fn new() -> Self { fn new() -> Self {
ContentSerializer { ContentSerializer { error: PhantomData }
error: PhantomData,
}
} }
} }
@@ -299,9 +295,7 @@ impl<E> Serializer for ContentSerializer<E>
Ok(Content::None) Ok(Content::None)
} }
fn serialize_some<T: ?Sized + Serialize>(self, fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Content, E> {
value: &T)
-> Result<Content, E> {
Ok(Content::Some(Box::new(try!(value.serialize(self))))) Ok(Content::Some(Box::new(try!(value.serialize(self)))))
} }
@@ -309,9 +303,7 @@ impl<E> Serializer for ContentSerializer<E>
Ok(Content::Unit) Ok(Content::Unit)
} }
fn serialize_unit_struct(self, fn serialize_unit_struct(self, name: &'static str) -> Result<Content, E> {
name: &'static str)
-> Result<Content, E> {
Ok(Content::UnitStruct(name)) Ok(Content::UnitStruct(name))
} }
@@ -336,36 +328,33 @@ impl<E> Serializer for ContentSerializer<E>
variant: &'static str, variant: &'static str,
value: &T) value: &T)
-> Result<Content, E> { -> Result<Content, E> {
Ok(Content::NewtypeVariant(name, variant_index, variant, Box::new(try!(value.serialize(self))))) Ok(Content::NewtypeVariant(name,
variant_index,
variant,
Box::new(try!(value.serialize(self)))))
} }
fn serialize_seq(self, fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
len: Option<usize>)
-> Result<Self::SerializeSeq, E> {
Ok(SerializeSeq { Ok(SerializeSeq {
fixed_size: false, fixed_size: false,
elements: Vec::with_capacity(len.unwrap_or(0)), elements: Vec::with_capacity(len.unwrap_or(0)),
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_seq_fixed_size(self, fn serialize_seq_fixed_size(self, size: usize) -> Result<Self::SerializeSeq, E> {
size: usize)
-> Result<Self::SerializeSeq, E> {
Ok(SerializeSeq { Ok(SerializeSeq {
fixed_size: true, fixed_size: true,
elements: Vec::with_capacity(size), elements: Vec::with_capacity(size),
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_tuple(self, fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
len: usize)
-> Result<Self::SerializeTuple, E> {
Ok(SerializeTuple { Ok(SerializeTuple {
elements: Vec::with_capacity(len), elements: Vec::with_capacity(len),
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_tuple_struct(self, fn serialize_tuple_struct(self,
@@ -373,10 +362,10 @@ impl<E> Serializer for ContentSerializer<E>
len: usize) len: usize)
-> Result<Self::SerializeTupleStruct, E> { -> Result<Self::SerializeTupleStruct, E> {
Ok(SerializeTupleStruct { Ok(SerializeTupleStruct {
name: name, name: name,
fields: Vec::with_capacity(len), fields: Vec::with_capacity(len),
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_tuple_variant(self, fn serialize_tuple_variant(self,
@@ -386,33 +375,28 @@ impl<E> Serializer for ContentSerializer<E>
len: usize) len: usize)
-> Result<Self::SerializeTupleVariant, E> { -> Result<Self::SerializeTupleVariant, E> {
Ok(SerializeTupleVariant { Ok(SerializeTupleVariant {
name: name, name: name,
variant_index: variant_index, variant_index: variant_index,
variant: variant, variant: variant,
fields: Vec::with_capacity(len), fields: Vec::with_capacity(len),
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_map(self, fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
len: Option<usize>)
-> Result<Self::SerializeMap, E> {
Ok(SerializeMap { Ok(SerializeMap {
entries: Vec::with_capacity(len.unwrap_or(0)), entries: Vec::with_capacity(len.unwrap_or(0)),
key: None, key: None,
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_struct(self, fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, E> {
name: &'static str,
len: usize)
-> Result<Self::SerializeStruct, E> {
Ok(SerializeStruct { Ok(SerializeStruct {
name: name, name: name,
fields: Vec::with_capacity(len), fields: Vec::with_capacity(len),
error: PhantomData, error: PhantomData,
}) })
} }
fn serialize_struct_variant(self, fn serialize_struct_variant(self,
@@ -422,12 +406,12 @@ impl<E> Serializer for ContentSerializer<E>
len: usize) len: usize)
-> Result<Self::SerializeStructVariant, E> { -> Result<Self::SerializeStructVariant, E> {
Ok(SerializeStructVariant { Ok(SerializeStructVariant {
name: name, name: name,
variant_index: variant_index, variant_index: variant_index,
variant: variant, variant: variant,
fields: Vec::with_capacity(len), fields: Vec::with_capacity(len),
error: PhantomData, error: PhantomData,
}) })
} }
} }
@@ -443,9 +427,7 @@ impl<E> ser::SerializeSeq for SerializeSeq<E>
type Ok = Content; type Ok = Content;
type Error = E; type Error = E;
fn serialize_element<T: ?Sized + Serialize>(&mut self, fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), E> {
value: &T)
-> Result<(), E> {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = try!(value.serialize(ContentSerializer::<E>::new()));
self.elements.push(value); self.elements.push(value);
Ok(()) Ok(())
@@ -453,10 +435,10 @@ impl<E> ser::SerializeSeq for SerializeSeq<E>
fn end(self) -> Result<Content, E> { fn end(self) -> Result<Content, E> {
Ok(if self.fixed_size { Ok(if self.fixed_size {
Content::SeqFixedSize(self.elements) Content::SeqFixedSize(self.elements)
} else { } else {
Content::Seq(self.elements) Content::Seq(self.elements)
}) })
} }
} }
@@ -471,9 +453,7 @@ impl<E> ser::SerializeTuple for SerializeTuple<E>
type Ok = Content; type Ok = Content;
type Error = E; type Error = E;
fn serialize_element<T: ?Sized + Serialize>(&mut self, fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), E> {
value: &T)
-> Result<(), E> {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = try!(value.serialize(ContentSerializer::<E>::new()));
self.elements.push(value); self.elements.push(value);
Ok(()) Ok(())
@@ -496,9 +476,7 @@ impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
type Ok = Content; type Ok = Content;
type Error = E; type Error = E;
fn serialize_field<T: ?Sized + Serialize>(&mut self, fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), E> {
value: &T)
-> Result<(), E> {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = try!(value.serialize(ContentSerializer::<E>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
@@ -523,9 +501,7 @@ impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
type Ok = Content; type Ok = Content;
type Error = E; type Error = E;
fn serialize_field<T: ?Sized + Serialize>(&mut self, fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), E> {
value: &T)
-> Result<(), E> {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = try!(value.serialize(ContentSerializer::<E>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
@@ -548,17 +524,13 @@ impl<E> ser::SerializeMap for SerializeMap<E>
type Ok = Content; type Ok = Content;
type Error = E; type Error = E;
fn serialize_key<T: ?Sized + Serialize>(&mut self, fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), E> {
key: &T)
-> Result<(), E> {
let key = try!(key.serialize(ContentSerializer::<E>::new())); let key = try!(key.serialize(ContentSerializer::<E>::new()));
self.key = Some(key); self.key = Some(key);
Ok(()) Ok(())
} }
fn serialize_value<T: ?Sized + Serialize>(&mut self, fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), E> {
value: &T)
-> Result<(), E> {
let key = self.key.take().expect("serialize_value called before serialize_key"); let key = self.key.take().expect("serialize_value called before serialize_key");
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = try!(value.serialize(ContentSerializer::<E>::new()));
self.entries.push((key, value)); self.entries.push((key, value));
+102 -31
View File
@@ -13,16 +13,14 @@ use collections::borrow::ToOwned;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use core::hash::{Hash, BuildHasher}; use core::hash::{Hash, BuildHasher};
#[cfg(feature = "unstable")]
use core::iter;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::net; use std::net;
#[cfg(feature = "unstable")] #[cfg(any(feature = "std", feature = "unstable"))]
use core::ops; use core::ops;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::path; use std::path;
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::ffi::{CString, CStr}; use std::ffi::{CString, CStr, OsString, OsStr};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::rc::Rc; use std::rc::Rc;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
@@ -38,6 +36,11 @@ use alloc::arc::Arc;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box; use alloc::boxed::Box;
use core::cell::{Cell, RefCell};
#[cfg(feature = "std")]
use std::sync::{Mutex, RwLock};
use core::marker::PhantomData; use core::marker::PhantomData;
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
@@ -262,37 +265,18 @@ impl<T> Serialize for VecDeque<T>
serialize_seq!(); serialize_seq!();
} }
#[cfg(feature = "unstable")] ///////////////////////////////////////////////////////////////////////////////
impl<A> Serialize for ops::Range<A>
where ops::Range<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
A: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
for e in self.clone() {
try!(seq.serialize_element(&e));
}
seq.end()
}
}
#[cfg(feature = "unstable")] #[cfg(feature = "std")]
impl<A> Serialize for ops::RangeInclusive<A> impl<Idx: Serialize> Serialize for ops::Range<Idx> {
where ops::RangeInclusive<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
A: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer where S: Serializer
{ {
let mut seq = try!(serializer.serialize_seq(Some(self.len()))); use super::SerializeStruct;
for e in self.clone() { let mut state = try!(serializer.serialize_struct("Range", 2));
try!(seq.serialize_element(&e)); try!(state.serialize_field("start", &self.start));
} try!(state.serialize_field("end", &self.end));
seq.end() state.end()
} }
} }
@@ -607,6 +591,58 @@ impl<'a, T: ?Sized> Serialize for Cow<'a, T>
} }
} }
impl<T> Serialize for Cell<T>
where T: Serialize + Copy
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
self.get().serialize(serializer)
}
}
impl<T> Serialize for RefCell<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
self.borrow().serialize(serializer)
}
}
#[cfg(feature = "std")]
impl<T> Serialize for Mutex<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match self.lock() {
Ok(locked) => locked.serialize(serializer),
Err(_) => Err(S::Error::custom("lock poison error while serializing")),
}
}
}
#[cfg(feature = "std")]
impl<T> Serialize for RwLock<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match self.read() {
Ok(locked) => locked.serialize(serializer),
Err(_) => Err(S::Error::custom("lock poison error while serializing")),
}
}
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
impl<T, E> Serialize for Result<T, E> impl<T, E> Serialize for Result<T, E>
@@ -735,6 +771,41 @@ impl Serialize for path::PathBuf {
} }
} }
#[cfg(all(feature = "std", any(unix, windows)))]
impl Serialize for OsStr {
#[cfg(unix)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
use std::os::unix::ffi::OsStrExt;
serializer.serialize_newtype_variant("OsString",
0,
"Unix",
self.as_bytes())
}
#[cfg(windows)]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
use std::os::windows::ffi::OsStrExt;
let val = self.encode_wide().collect::<Vec<_>>();
serializer.serialize_newtype_variant("OsString",
1,
"Windows",
&val)
}
}
#[cfg(all(feature = "std", any(unix, windows)))]
#[cfg(feature = "std")]
impl Serialize for OsString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
self.as_os_str().serialize(serializer)
}
}
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
impl<T> Serialize for NonZero<T> impl<T> Serialize for NonZero<T>
where T: Serialize + Zeroable where T: Serialize + Zeroable
+7 -4
View File
@@ -61,6 +61,10 @@
//! - Rc\<T\> //! - Rc\<T\>
//! - Arc\<T\> //! - Arc\<T\>
//! - Cow\<'a, T\> //! - Cow\<'a, T\>
//! - Cell\<T\>
//! - RefCell\<T\>
//! - Mutex\<T\>
//! - RwLock\<T\>
//! - **Collection types**: //! - **Collection types**:
//! - BTreeMap\<K, V\> //! - BTreeMap\<K, V\>
//! - BTreeSet\<T\> //! - BTreeSet\<T\>
@@ -71,12 +75,11 @@
//! - VecDeque\<T\> //! - VecDeque\<T\>
//! - Vec\<T\> //! - Vec\<T\>
//! - EnumSet\<T\> (unstable) //! - EnumSet\<T\> (unstable)
//! - Range\<T\> (unstable)
//! - RangeInclusive\<T\> (unstable)
//! - **Miscellaneous standard library types**: //! - **Miscellaneous standard library types**:
//! - Duration //! - Duration
//! - Path //! - Path
//! - PathBuf //! - PathBuf
//! - Range\<T\>
//! - NonZero\<T\> (unstable) //! - NonZero\<T\> (unstable)
//! - **Net types**: //! - **Net types**:
//! - IpAddr //! - IpAddr
@@ -646,7 +649,7 @@ pub trait Serializer: Sized {
/// ``` /// ```
#[cfg(any(feature = "std", feature = "collections"))] #[cfg(any(feature = "std", feature = "collections"))]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where T: Display, where T: Display
{ {
let mut string = String::new(); let mut string = String::new();
write!(string, "{}", value).unwrap(); write!(string, "{}", value).unwrap();
@@ -677,7 +680,7 @@ pub trait Serializer: Sized {
/// ``` /// ```
#[cfg(not(any(feature = "std", feature = "collections")))] #[cfg(not(any(feature = "std", feature = "collections")))]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error> fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where T: Display, where T: Display
{ {
// TODO https://github.com/serde-rs/serde/issues/805 // TODO https://github.com/serde-rs/serde/issues/805
// Remove this impl and force no_std formats to implement collect_str. // Remove this impl and force no_std formats to implement collect_str.
+13 -11
View File
@@ -17,12 +17,12 @@ pub fn serialize_tagged_newtype<S, T>(serializer: S,
T: Serialize T: Serialize
{ {
value.serialize(TaggedSerializer { value.serialize(TaggedSerializer {
type_ident: type_ident, type_ident: type_ident,
variant_ident: variant_ident, variant_ident: variant_ident,
tag: tag, tag: tag,
variant_name: variant_name, variant_name: variant_name,
delegate: serializer, delegate: serializer,
}) })
} }
struct TaggedSerializer<S> { struct TaggedSerializer<S> {
@@ -81,7 +81,9 @@ impl Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, write!(formatter,
"cannot serialize tagged newtype variant {}::{} containing {}", "cannot serialize tagged newtype variant {}::{} containing {}",
self.type_ident, self.variant_ident, self.ty) self.type_ident,
self.variant_ident,
self.ty)
} }
} }
@@ -90,10 +92,10 @@ impl<S> TaggedSerializer<S>
{ {
fn bad_type(self, what: Unsupported) -> S::Error { fn bad_type(self, what: Unsupported) -> S::Error {
ser::Error::custom(Error { ser::Error::custom(Error {
type_ident: self.type_ident, type_ident: self.type_ident,
variant_ident: self.variant_ident, variant_ident: self.variant_ident,
ty: what, ty: what,
}) })
} }
} }
+2 -2
View File
@@ -59,8 +59,8 @@ const Pattern_White_Space_table: &'static [(char, char)] = &[('\u{9}', '\u{d}'),
fn bsearch_range_table(c: char, r: &'static [(char, char)]) -> bool { fn bsearch_range_table(c: char, r: &'static [(char, char)]) -> bool {
use core::cmp::Ordering::{Equal, Less, Greater}; use core::cmp::Ordering::{Equal, Less, Greater};
r.binary_search_by(|&(lo, hi)| if c < lo { r.binary_search_by(|&(lo, hi)| if c < lo {
Greater Greater
} else if hi < c { } else if hi < c {
Less Less
} else { } else {
Equal Equal
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_codegen_internals" name = "serde_codegen_internals"
version = "0.14.1" version = "0.14.2"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "AST representation used by Serde codegen. Unstable." description = "AST representation used by Serde codegen. Unstable."
+39
View File
@@ -98,6 +98,8 @@ pub struct Item {
ser_bound: Option<Vec<syn::WherePredicate>>, ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>, de_bound: Option<Vec<syn::WherePredicate>>,
tag: EnumTag, tag: EnumTag,
from_type: Option<syn::Ty>,
into_type: Option<syn::Ty>,
} }
/// Styles of representing an enum. /// Styles of representing an enum.
@@ -145,6 +147,8 @@ impl Item {
let mut untagged = BoolAttr::none(cx, "untagged"); let mut untagged = BoolAttr::none(cx, "untagged");
let mut internal_tag = Attr::none(cx, "tag"); let mut internal_tag = Attr::none(cx, "tag");
let mut content = Attr::none(cx, "content"); let mut content = Attr::none(cx, "content");
let mut from_type = Attr::none(cx, "from");
let mut into_type = Attr::none(cx, "into");
for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items { for meta_item in meta_items {
@@ -270,6 +274,20 @@ impl Item {
} }
} }
// Parse `#[serde(from = "Type")]
MetaItem(NameValue(ref name, ref lit)) if name == "from" => {
if let Ok(from_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
from_type.set_opt(Some(from_ty));
}
}
// Parse `#[serde(into = "Type")]
MetaItem(NameValue(ref name, ref lit)) if name == "into" => {
if let Ok(into_ty) = parse_lit_into_ty(cx, name.as_ref(), lit) {
into_type.set_opt(Some(into_ty));
}
}
MetaItem(ref meta_item) => { MetaItem(ref meta_item) => {
cx.error(format!("unknown serde container attribute `{}`", cx.error(format!("unknown serde container attribute `{}`",
meta_item.name())); meta_item.name()));
@@ -339,6 +357,8 @@ impl Item {
ser_bound: ser_bound.get(), ser_bound: ser_bound.get(),
de_bound: de_bound.get(), de_bound: de_bound.get(),
tag: tag, tag: tag,
from_type: from_type.get(),
into_type: into_type.get(),
} }
} }
@@ -369,6 +389,14 @@ impl Item {
pub fn tag(&self) -> &EnumTag { pub fn tag(&self) -> &EnumTag {
&self.tag &self.tag
} }
pub fn from_type(&self) -> Option<&syn::Ty> {
self.from_type.as_ref()
}
pub fn into_type(&self) -> Option<&syn::Ty> {
self.into_type.as_ref()
}
} }
/// Represents variant attribute information /// Represents variant attribute information
@@ -797,3 +825,14 @@ fn parse_lit_into_where(cx: &Ctxt,
syn::parse_where_clause(&where_string).map(|wh| wh.predicates).map_err(|err| cx.error(err)) syn::parse_where_clause(&where_string).map(|wh| wh.predicates).map_err(|err| cx.error(err))
} }
fn parse_lit_into_ty(cx: &Ctxt,
attr_name: &str,
lit: &syn::Lit)
-> Result<syn::Ty, ()> {
let string = try!(get_string_from_lit(cx, attr_name, attr_name, lit));
syn::parse_type(&string).map_err(|_| {
cx.error(format!("failed to parse type: {} = {:?}", attr_name, string))
})
}
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "0.9.11" version = "0.9.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@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)]"
@@ -23,5 +23,5 @@ proc-macro = true
[dependencies] [dependencies]
quote = "0.3.8" quote = "0.3.8"
serde_codegen_internals = { version = "=0.14.1", default-features = false, path = "../serde_codegen_internals" } serde_codegen_internals = { version = "=0.14.2", default-features = false, path = "../serde_codegen_internals" }
syn = { version = "0.11", features = ["visit"] } syn = { version = "0.11", features = ["visit"] }
+118 -106
View File
@@ -27,7 +27,7 @@ pub fn expand_derive_deserialize(item: &syn::DeriveInput) -> Result<Tokens, Stri
extern crate serde as _serde; extern crate serde as _serde;
#[automatically_derived] #[automatically_derived]
impl #impl_generics _serde::Deserialize for #ident #ty_generics #where_clause { impl #impl_generics _serde::Deserialize for #ident #ty_generics #where_clause {
fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<Self, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
where __D: _serde::Deserializer where __D: _serde::Deserializer
{ {
#body #body
@@ -85,36 +85,46 @@ fn requires_default(attrs: &attr::Field) -> bool {
} }
fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment { fn deserialize_body(item: &Item, generics: &syn::Generics) -> Fragment {
match item.body { if let Some(from_type) = item.attrs.from_type() {
Body::Enum(ref variants) => { deserialize_from(from_type)
deserialize_item_enum(&item.ident, generics, variants, &item.attrs) } else {
} match item.body {
Body::Struct(Style::Struct, ref fields) => { Body::Enum(ref variants) => {
if fields.iter().any(|field| field.ident.is_none()) { deserialize_item_enum(&item.ident, generics, variants, &item.attrs)
panic!("struct has unnamed fields");
} }
Body::Struct(Style::Struct, ref fields) => {
deserialize_struct(&item.ident, if fields.iter().any(|field| field.ident.is_none()) {
None, panic!("struct has unnamed fields");
generics, }
fields, deserialize_struct(&item.ident,
&item.attrs, None,
None) generics,
} fields,
Body::Struct(Style::Tuple, ref fields) | &item.attrs,
Body::Struct(Style::Newtype, ref fields) => { None)
if fields.iter().any(|field| field.ident.is_some()) {
panic!("tuple struct has named fields");
} }
Body::Struct(Style::Tuple, ref fields) |
deserialize_tuple(&item.ident, Body::Struct(Style::Newtype, ref fields) => {
None, if fields.iter().any(|field| field.ident.is_some()) {
generics, panic!("tuple struct has named fields");
fields, }
&item.attrs, deserialize_tuple(&item.ident,
None) None,
generics,
fields,
&item.attrs,
None)
}
Body::Struct(Style::Unit, _) => deserialize_unit_struct(&item.ident, &item.attrs),
} }
Body::Struct(Style::Unit, _) => deserialize_unit_struct(&item.ident, &item.attrs), }
}
fn deserialize_from(from_type: &syn::Ty) -> Fragment {
quote_block! {
_serde::export::Result::map(
<#from_type as _serde::Deserialize>::deserialize(__deserializer),
_serde::export::From::from)
} }
} }
@@ -135,20 +145,20 @@ fn deserialize_unit_struct(ident: &syn::Ident, item_attrs: &attr::Item) -> Fragm
#[inline] #[inline]
fn visit_unit<__E>(self) -> _serde::export::Result<#ident, __E> fn visit_unit<__E>(self) -> _serde::export::Result<#ident, __E>
where __E: _serde::de::Error, where __E: _serde::de::Error
{ {
_serde::export::Ok(#ident) _serde::export::Ok(#ident)
} }
#[inline] #[inline]
fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#ident, __V::Error> fn visit_seq<__V>(self, _: __V) -> _serde::export::Result<#ident, __V::Error>
where __V: _serde::de::SeqVisitor, where __V: _serde::de::SeqVisitor
{ {
_serde::export::Ok(#ident) _serde::export::Ok(#ident)
} }
} }
deserializer.deserialize_unit_struct(#type_name, __Visitor) _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor)
} }
} }
@@ -187,20 +197,20 @@ fn deserialize_tuple(ident: &syn::Ident,
let dispatch = if let Some(deserializer) = deserializer { let dispatch = if let Some(deserializer) = deserializer {
quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr)) quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr))
} else if is_enum { } else if is_enum {
quote!(_serde::de::VariantVisitor::visit_tuple(visitor, #nfields, #visitor_expr)) quote!(_serde::de::VariantVisitor::visit_tuple(__visitor, #nfields, #visitor_expr))
} else if nfields == 1 { } else if nfields == 1 {
let type_name = item_attrs.name().deserialize_name(); let type_name = item_attrs.name().deserialize_name();
quote!(_serde::Deserializer::deserialize_newtype_struct(deserializer, #type_name, #visitor_expr)) quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
} else { } else {
let type_name = item_attrs.name().deserialize_name(); let type_name = item_attrs.name().deserialize_name();
quote!(_serde::Deserializer::deserialize_tuple_struct(deserializer, #type_name, #nfields, #visitor_expr)) quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
}; };
let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing()); let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
let visitor_var = if all_skipped { let visitor_var = if all_skipped {
quote!(_) quote!(_)
} else { } else {
quote!(mut visitor) quote!(mut __visitor)
}; };
quote_block! { quote_block! {
@@ -255,21 +265,22 @@ fn deserialize_seq(ident: &syn::Ident,
let visit = match field.attrs.deserialize_with() { let visit = match field.attrs.deserialize_with() {
None => { None => {
let field_ty = &field.ty; let field_ty = &field.ty;
quote!(try!(_serde::de::SeqVisitor::visit::<#field_ty>(&mut visitor))) quote!(try!(_serde::de::SeqVisitor::visit::<#field_ty>(&mut __visitor)))
} }
Some(path) => { Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_with( let (wrapper, wrapper_ty) = wrap_deserialize_with(
ident, generics, field.ty, path); ident, generics, field.ty, path);
quote!({ quote!({
#wrapper #wrapper
try!(_serde::de::SeqVisitor::visit::<#wrapper_ty>(&mut visitor)) _serde::export::Option::map(
.map(|wrap| wrap.value) try!(_serde::de::SeqVisitor::visit::<#wrapper_ty>(&mut __visitor)),
|__wrap| __wrap.value)
}) })
} }
}; };
let assign = quote! { let assign = quote! {
let #var = match #visit { let #var = match #visit {
Some(value) => { value }, Some(__value) => __value,
None => { None => {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
} }
@@ -321,7 +332,7 @@ fn deserialize_newtype_struct(ident: &syn::Ident,
quote! { quote! {
#[inline] #[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error> fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer, where __E: _serde::Deserializer
{ {
_serde::export::Ok(#type_path(#value)) _serde::export::Ok(#type_path(#value))
} }
@@ -366,12 +377,12 @@ fn deserialize_struct(ident: &syn::Ident,
} }
} else if is_enum { } else if is_enum {
quote! { quote! {
_serde::de::VariantVisitor::visit_struct(visitor, FIELDS, #visitor_expr) _serde::de::VariantVisitor::visit_struct(__visitor, FIELDS, #visitor_expr)
} }
} else { } else {
let type_name = item_attrs.name().deserialize_name(); let type_name = item_attrs.name().deserialize_name();
quote! { quote! {
_serde::Deserializer::deserialize_struct(deserializer, #type_name, FIELDS, #visitor_expr) _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
} }
}; };
@@ -379,7 +390,7 @@ fn deserialize_struct(ident: &syn::Ident,
let visitor_var = if all_skipped { let visitor_var = if all_skipped {
quote!(_) quote!(_)
} else { } else {
quote!(mut visitor) quote!(mut __visitor)
}; };
let visit_seq = if is_untagged { let visit_seq = if is_untagged {
@@ -413,7 +424,7 @@ fn deserialize_struct(ident: &syn::Ident,
#visit_seq #visit_seq
#[inline] #[inline]
fn visit_map<__V>(self, mut visitor: __V) -> _serde::export::Result<Self::Value, __V::Error> fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result<Self::Value, __V::Error>
where __V: _serde::de::MapVisitor where __V: _serde::de::MapVisitor
{ {
#visit_map #visit_map
@@ -495,7 +506,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident,
item_attrs)); item_attrs));
quote! { quote! {
(__Field::#variant_name, visitor) => #block (__Field::#variant_name, __visitor) => #block
} }
}); });
@@ -505,14 +516,15 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident,
// all variants have `#[serde(skip_deserializing)]`. // all variants have `#[serde(skip_deserializing)]`.
quote! { quote! {
// FIXME: Once we drop support for Rust 1.15: // FIXME: Once we drop support for Rust 1.15:
// let _serde::export::Err(err) = _serde::de::EnumVisitor::visit_variant::<__Field>(visitor); // let _serde::export::Err(__err) = _serde::de::EnumVisitor::visit_variant::<__Field>(__visitor);
// _serde::export::Err(err) // _serde::export::Err(__err)
_serde::de::EnumVisitor::visit_variant::<__Field>(visitor) _serde::export::Result::map(
.map(|(impossible, _)| match impossible {}) _serde::de::EnumVisitor::visit_variant::<__Field>(__visitor),
|(__impossible, _)| match __impossible {})
} }
} else { } else {
quote! { quote! {
match try!(_serde::de::EnumVisitor::visit_variant(visitor)) { match try!(_serde::de::EnumVisitor::visit_variant(__visitor)) {
#(#variant_arms)* #(#variant_arms)*
} }
} }
@@ -532,8 +544,8 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident,
_serde::export::fmt::Formatter::write_str(formatter, #expecting) _serde::export::fmt::Formatter::write_str(formatter, #expecting)
} }
fn visit_enum<__V>(self, visitor: __V) -> _serde::export::Result<Self::Value, __V::Error> fn visit_enum<__V>(self, __visitor: __V) -> _serde::export::Result<Self::Value, __V::Error>
where __V: _serde::de::EnumVisitor, where __V: _serde::de::EnumVisitor
{ {
#match_variant #match_variant
} }
@@ -541,7 +553,7 @@ fn deserialize_externally_tagged_enum(ident: &syn::Ident,
#variants_stmt #variants_stmt
_serde::Deserializer::deserialize_enum(deserializer, #type_name, VARIANTS, _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
__Visitor { __Visitor {
marker: _serde::export::PhantomData::<#ident #ty_generics>, marker: _serde::export::PhantomData::<#ident #ty_generics>,
}) })
@@ -581,7 +593,7 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident,
generics, generics,
variant, variant,
item_attrs, item_attrs,
quote!(_serde::de::private::ContentDeserializer::<__D::Error>::new(_tagged.content)), quote!(_serde::de::private::ContentDeserializer::<__D::Error>::new(__tagged.content)),
)); ));
quote! { quote! {
@@ -594,11 +606,11 @@ fn deserialize_internally_tagged_enum(ident: &syn::Ident,
#variants_stmt #variants_stmt
let _tagged = try!(_serde::Deserializer::deserialize( let __tagged = try!(_serde::Deserializer::deserialize(
deserializer, __deserializer,
_serde::de::private::TaggedContentVisitor::<__Field>::new(#tag))); _serde::de::private::TaggedContentVisitor::<__Field>::new(#tag)));
match _tagged.tag { match __tagged.tag {
#(#variant_arms)* #(#variant_arms)*
} }
} }
@@ -639,7 +651,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
generics, generics,
variant, variant,
item_attrs, item_attrs,
quote!(_deserializer), quote!(__deserializer),
)); ));
quote! { quote! {
@@ -696,7 +708,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
let visit_third_key = quote! { let visit_third_key = quote! {
// Visit the third key in the map, hopefully there isn't one. // Visit the third key in the map, hopefully there isn't one.
match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) {
_serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => {
_serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag))
} }
@@ -720,7 +732,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
impl #impl_generics _serde::de::DeserializeSeed for __Seed #ty_generics #where_clause { impl #impl_generics _serde::de::DeserializeSeed for __Seed #ty_generics #where_clause {
type Value = #ident #ty_generics; type Value = #ident #ty_generics;
fn deserialize<__D>(self, _deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error> fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error>
where __D: _serde::Deserializer where __D: _serde::Deserializer
{ {
match self.field { match self.field {
@@ -740,24 +752,24 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
_serde::export::fmt::Formatter::write_str(formatter, #expecting) _serde::export::fmt::Formatter::write_str(formatter, #expecting)
} }
fn visit_map<__V>(self, mut visitor: __V) -> _serde::export::Result<Self::Value, __V::Error> fn visit_map<__V>(self, mut __visitor: __V) -> _serde::export::Result<Self::Value, __V::Error>
where __V: _serde::de::MapVisitor where __V: _serde::de::MapVisitor
{ {
// Visit the first key. // Visit the first key.
match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) {
// First key is the tag. // First key is the tag.
_serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => {
// Parse the tag. // Parse the tag.
let __field = try!(_serde::de::MapVisitor::visit_value(&mut visitor)); let __field = try!(_serde::de::MapVisitor::visit_value(&mut __visitor));
// Visit the second key. // Visit the second key.
match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) {
// Second key is a duplicate of the tag. // Second key is a duplicate of the tag.
_serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => {
_serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag)) _serde::export::Err(<__V::Error as _serde::de::Error>::duplicate_field(#tag))
} }
// Second key is the content. // Second key is the content.
_serde::export::Some(_serde::de::private::TagOrContentField::Content) => { _serde::export::Some(_serde::de::private::TagOrContentField::Content) => {
let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut visitor, __Seed { field: __field, marker: _serde::export::PhantomData })); let __ret = try!(_serde::de::MapVisitor::visit_value_seed(&mut __visitor, __Seed { field: __field, marker: _serde::export::PhantomData }));
// Visit the third key, hopefully there isn't one. // Visit the third key, hopefully there isn't one.
#visit_third_key #visit_third_key
} }
@@ -768,14 +780,14 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
// First key is the content. // First key is the content.
_serde::export::Some(_serde::de::private::TagOrContentField::Content) => { _serde::export::Some(_serde::de::private::TagOrContentField::Content) => {
// Buffer up the content. // Buffer up the content.
let __content = try!(_serde::de::MapVisitor::visit_value::<_serde::de::private::Content>(&mut visitor)); let __content = try!(_serde::de::MapVisitor::visit_value::<_serde::de::private::Content>(&mut __visitor));
// Visit the second key. // Visit the second key.
match try!(_serde::de::MapVisitor::visit_key_seed(&mut visitor, #tag_or_content)) { match try!(_serde::de::MapVisitor::visit_key_seed(&mut __visitor, #tag_or_content)) {
// Second key is the tag. // Second key is the tag.
_serde::export::Some(_serde::de::private::TagOrContentField::Tag) => { _serde::export::Some(_serde::de::private::TagOrContentField::Tag) => {
let _deserializer = _serde::de::private::ContentDeserializer::<__V::Error>::new(__content); let __deserializer = _serde::de::private::ContentDeserializer::<__V::Error>::new(__content);
// Parse the tag. // Parse the tag.
let __ret = try!(match try!(_serde::de::MapVisitor::visit_value(&mut visitor)) { let __ret = try!(match try!(_serde::de::MapVisitor::visit_value(&mut __visitor)) {
// Deserialize the buffered content now that we know the variant. // Deserialize the buffered content now that we know the variant.
#(#variant_arms)* #(#variant_arms)*
}); });
@@ -799,14 +811,14 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
} }
} }
fn visit_seq<__V>(self, mut visitor: __V) -> _serde::export::Result<Self::Value, __V::Error> fn visit_seq<__V>(self, mut __visitor: __V) -> _serde::export::Result<Self::Value, __V::Error>
where __V: _serde::de::SeqVisitor where __V: _serde::de::SeqVisitor
{ {
// Visit the first element - the tag. // Visit the first element - the tag.
match try!(_serde::de::SeqVisitor::visit(&mut visitor)) { match try!(_serde::de::SeqVisitor::visit(&mut __visitor)) {
_serde::export::Some(__field) => { _serde::export::Some(__field) => {
// Visit the second element - the content. // Visit the second element - the content.
match try!(_serde::de::SeqVisitor::visit_seed(&mut visitor, __Seed { field: __field, marker: _serde::export::PhantomData })) { match try!(_serde::de::SeqVisitor::visit_seed(&mut __visitor, __Seed { field: __field, marker: _serde::export::PhantomData })) {
_serde::export::Some(__ret) => _serde::export::Ok(__ret), _serde::export::Some(__ret) => _serde::export::Ok(__ret),
// There is no second element. // There is no second element.
_serde::export::None => { _serde::export::None => {
@@ -823,7 +835,7 @@ fn deserialize_adjacently_tagged_enum(ident: &syn::Ident,
} }
const FIELDS: &'static [&'static str] = &[#tag, #content]; const FIELDS: &'static [&'static str] = &[#tag, #content];
_serde::Deserializer::deserialize_struct(deserializer, #type_name, FIELDS, _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS,
__Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> }) __Visitor { marker: _serde::export::PhantomData::<#ident #ty_generics> })
} }
} }
@@ -841,7 +853,7 @@ fn deserialize_untagged_enum(ident: &syn::Ident,
generics, generics,
variant, variant,
item_attrs, item_attrs,
quote!(_serde::de::private::ContentRefDeserializer::<__D::Error>::new(&_content)), quote!(_serde::de::private::ContentRefDeserializer::<__D::Error>::new(&__content)),
)) ))
}); });
@@ -854,11 +866,11 @@ fn deserialize_untagged_enum(ident: &syn::Ident,
let fallthrough_msg = format!("data did not match any variant of untagged enum {}", ident); let fallthrough_msg = format!("data did not match any variant of untagged enum {}", ident);
quote_block! { quote_block! {
let _content = try!(<_serde::de::private::Content as _serde::Deserialize>::deserialize(deserializer)); let __content = try!(<_serde::de::private::Content as _serde::Deserialize>::deserialize(__deserializer));
#( #(
if let _serde::export::Ok(ok) = #attempts { if let _serde::export::Ok(__ok) = #attempts {
return _serde::export::Ok(ok); return _serde::export::Ok(__ok);
} }
)* )*
@@ -876,7 +888,7 @@ fn deserialize_externally_tagged_variant(ident: &syn::Ident,
match variant.style { match variant.style {
Style::Unit => { Style::Unit => {
quote_block! { quote_block! {
try!(_serde::de::VariantVisitor::visit_unit(visitor)); try!(_serde::de::VariantVisitor::visit_unit(__visitor));
_serde::export::Ok(#ident::#variant_ident) _serde::export::Ok(#ident::#variant_ident)
} }
} }
@@ -990,7 +1002,7 @@ fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident,
let field_ty = &field.ty; let field_ty = &field.ty;
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(
_serde::de::VariantVisitor::visit_newtype::<#field_ty>(visitor), _serde::de::VariantVisitor::visit_newtype::<#field_ty>(__visitor),
#ident::#variant_ident) #ident::#variant_ident)
} }
} }
@@ -1000,8 +1012,8 @@ fn deserialize_externally_tagged_newtype_variant(ident: &syn::Ident,
quote_block! { quote_block! {
#wrapper #wrapper
_serde::export::Result::map( _serde::export::Result::map(
_serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(visitor), _serde::de::VariantVisitor::visit_newtype::<#wrapper_ty>(__visitor),
|_wrapper| #ident::#variant_ident(_wrapper.value)) |__wrapper| #ident::#variant_ident(__wrapper.value))
} }
} }
} }
@@ -1029,7 +1041,7 @@ fn deserialize_untagged_newtype_variant(ident: &syn::Ident,
#wrapper #wrapper
_serde::export::Result::map( _serde::export::Result::map(
<#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer),
|_wrapper| #ident::#variant_ident(_wrapper.value)) |__wrapper| #ident::#variant_ident(__wrapper.value))
} }
} }
} }
@@ -1053,15 +1065,15 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
let variant_indices = 0u32..; let variant_indices = 0u32..;
let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len()); let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
Some(quote! { Some(quote! {
fn visit_u32<__E>(self, value: u32) -> _serde::export::Result<__Field, __E> fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error where __E: _serde::de::Error
{ {
match value { match __value {
#( #(
#variant_indices => _serde::export::Ok(__Field::#field_idents), #variant_indices => _serde::export::Ok(__Field::#field_idents),
)* )*
_ => _serde::export::Err(_serde::de::Error::invalid_value( _ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(value as u64), _serde::de::Unexpected::Unsigned(__value as u64),
&#fallthrough_msg)) &#fallthrough_msg))
} }
} }
@@ -1072,11 +1084,11 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
let fallthrough_arm = if is_variant { let fallthrough_arm = if is_variant {
quote! { quote! {
_serde::export::Err(_serde::de::Error::unknown_variant(value, VARIANTS)) _serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
} }
} else if item_attrs.deny_unknown_fields() { } else if item_attrs.deny_unknown_fields() {
quote! { quote! {
_serde::export::Err(_serde::de::Error::unknown_field(value, FIELDS)) _serde::export::Err(_serde::de::Error::unknown_field(__value, FIELDS))
} }
} else { } else {
quote! { quote! {
@@ -1086,7 +1098,7 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() { let bytes_to_str = if is_variant || item_attrs.deny_unknown_fields() {
Some(quote! { Some(quote! {
let value = &_serde::export::from_utf8_lossy(value); let __value = &_serde::export::from_utf8_lossy(__value);
}) })
} else { } else {
None None
@@ -1101,8 +1113,8 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
impl _serde::Deserialize for __Field { impl _serde::Deserialize for __Field {
#[inline] #[inline]
fn deserialize<__D>(deserializer: __D) -> _serde::export::Result<__Field, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<__Field, __D::Error>
where __D: _serde::Deserializer, where __D: _serde::Deserializer
{ {
struct __FieldVisitor; struct __FieldVisitor;
@@ -1115,10 +1127,10 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
#visit_index #visit_index
fn visit_str<__E>(self, value: &str) -> _serde::export::Result<__Field, __E> fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error where __E: _serde::de::Error
{ {
match value { match __value {
#( #(
#field_strs => _serde::export::Ok(__Field::#field_idents), #field_strs => _serde::export::Ok(__Field::#field_idents),
)* )*
@@ -1126,10 +1138,10 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
} }
} }
fn visit_bytes<__E>(self, value: &[u8]) -> _serde::export::Result<__Field, __E> fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<__Field, __E>
where __E: _serde::de::Error where __E: _serde::de::Error
{ {
match value { match __value {
#( #(
#field_bytes => _serde::export::Ok(__Field::#field_idents), #field_bytes => _serde::export::Ok(__Field::#field_idents),
)* )*
@@ -1141,7 +1153,7 @@ fn deserialize_field_visitor(fields: Vec<(String, Ident)>,
} }
} }
_serde::Deserializer::deserialize_struct_field(deserializer, __FieldVisitor) _serde::Deserializer::deserialize_struct_field(__deserializer, __FieldVisitor)
} }
} }
} }
@@ -1205,7 +1217,7 @@ fn deserialize_map(ident: &syn::Ident,
None => { None => {
let field_ty = &field.ty; let field_ty = &field.ty;
quote! { quote! {
try!(_serde::de::MapVisitor::visit_value::<#field_ty>(&mut visitor)) try!(_serde::de::MapVisitor::visit_value::<#field_ty>(&mut __visitor))
} }
} }
Some(path) => { Some(path) => {
@@ -1213,7 +1225,7 @@ fn deserialize_map(ident: &syn::Ident,
ident, generics, field.ty, path); ident, generics, field.ty, path);
quote!({ quote!({
#wrapper #wrapper
try!(_serde::de::MapVisitor::visit_value::<#wrapper_ty>(&mut visitor)).value try!(_serde::de::MapVisitor::visit_value::<#wrapper_ty>(&mut __visitor)).value
}) })
} }
}; };
@@ -1232,7 +1244,7 @@ fn deserialize_map(ident: &syn::Ident,
None None
} else { } else {
Some(quote! { Some(quote! {
_ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::impls::IgnoredAny>(&mut visitor)); } _ => { let _ = try!(_serde::de::MapVisitor::visit_value::<_serde::de::impls::IgnoredAny>(&mut __visitor)); }
}) })
}; };
@@ -1240,14 +1252,15 @@ fn deserialize_map(ident: &syn::Ident,
let match_keys = if item_attrs.deny_unknown_fields() && all_skipped { let match_keys = if item_attrs.deny_unknown_fields() && all_skipped {
quote! { quote! {
// FIXME: Once we drop support for Rust 1.15: // FIXME: Once we drop support for Rust 1.15:
// let _serde::export::None::<__Field> = try!(_serde::de::MapVisitor::visit_key(&mut visitor)); // let _serde::export::None::<__Field> = try!(_serde::de::MapVisitor::visit_key(&mut __visitor));
try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut visitor)) _serde::export::Option::map(
.map(|impossible| match impossible {}); try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut __visitor)),
|__impossible| match __impossible {});
} }
} else { } else {
quote! { quote! {
while let _serde::export::Some(key) = try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut visitor)) { while let _serde::export::Some(__key) = try!(_serde::de::MapVisitor::visit_key::<__Field>(&mut __visitor)) {
match key { match __key {
#(#value_arms)* #(#value_arms)*
#ignored_arm #ignored_arm
} }
@@ -1330,12 +1343,11 @@ fn wrap_deserialize_with(ident: &syn::Ident,
} }
impl #impl_generics _serde::Deserialize for __DeserializeWith #ty_generics #where_clause { impl #impl_generics _serde::Deserialize for __DeserializeWith #ty_generics #where_clause {
fn deserialize<__D>(__d: __D) -> _serde::export::Result<Self, __D::Error> fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
where __D: _serde::Deserializer where __D: _serde::Deserializer
{ {
let value = try!(#deserialize_with(__d));
_serde::export::Ok(__DeserializeWith { _serde::export::Ok(__DeserializeWith {
value: value, value: try!(#deserialize_with(__deserializer)),
phantom: _serde::export::PhantomData, phantom: _serde::export::PhantomData,
}) })
} }
+49 -39
View File
@@ -23,7 +23,7 @@ pub fn expand_derive_serialize(item: &syn::DeriveInput) -> Result<Tokens, String
extern crate serde as _serde; extern crate serde as _serde;
#[automatically_derived] #[automatically_derived]
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause { impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer where __S: _serde::Serializer
{ {
#body #body
@@ -61,28 +61,38 @@ fn needs_serialize_bound(attrs: &attr::Field) -> bool {
} }
fn serialize_body(item: &Item, generics: &syn::Generics) -> Fragment { fn serialize_body(item: &Item, generics: &syn::Generics) -> Fragment {
match item.body { if let Some(into_type) = item.attrs.into_type() {
Body::Enum(ref variants) => { serialize_into(into_type)
serialize_item_enum(&item.ident, generics, variants, &item.attrs) } else {
} match item.body {
Body::Struct(Style::Struct, ref fields) => { Body::Enum(ref variants) => {
if fields.iter().any(|field| field.ident.is_none()) { serialize_item_enum(&item.ident, generics, variants, &item.attrs)
panic!("struct has unnamed fields");
} }
Body::Struct(Style::Struct, ref fields) => {
serialize_struct(&item.ident, generics, fields, &item.attrs) if fields.iter().any(|field| field.ident.is_none()) {
} panic!("struct has unnamed fields");
Body::Struct(Style::Tuple, ref fields) => { }
if fields.iter().any(|field| field.ident.is_some()) { serialize_struct(&item.ident, generics, fields, &item.attrs)
panic!("tuple struct has named fields");
} }
Body::Struct(Style::Tuple, ref fields) => {
if fields.iter().any(|field| field.ident.is_some()) {
panic!("tuple struct has named fields");
}
serialize_tuple_struct(&item.ident, generics, fields, &item.attrs)
}
Body::Struct(Style::Newtype, ref fields) => {
serialize_newtype_struct(&item.ident, generics, &fields[0], &item.attrs)
}
Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs),
}
}
}
serialize_tuple_struct(&item.ident, generics, fields, &item.attrs) fn serialize_into(into_type: &syn::Ty) -> Fragment {
} quote_block! {
Body::Struct(Style::Newtype, ref fields) => { _serde::Serialize::serialize(
serialize_newtype_struct(&item.ident, generics, &fields[0], &item.attrs) &<Self as _serde::export::Into<#into_type>>::into(_serde::export::Clone::clone(self)),
} __serializer)
Body::Struct(Style::Unit, _) => serialize_unit_struct(&item.attrs),
} }
} }
@@ -90,7 +100,7 @@ fn serialize_unit_struct(item_attrs: &attr::Item) -> Fragment {
let type_name = item_attrs.name().serialize_name(); let type_name = item_attrs.name().serialize_name();
quote_expr! { quote_expr! {
_serde::Serializer::serialize_unit_struct(_serializer, #type_name) _serde::Serializer::serialize_unit_struct(__serializer, #type_name)
} }
} }
@@ -107,7 +117,7 @@ fn serialize_newtype_struct(ident: &syn::Ident,
} }
quote_expr! { quote_expr! {
_serde::Serializer::serialize_newtype_struct(_serializer, #type_name, #field_expr) _serde::Serializer::serialize_newtype_struct(__serializer, #type_name, #field_expr)
} }
} }
@@ -128,7 +138,7 @@ fn serialize_tuple_struct(ident: &syn::Ident,
let let_mut = mut_if(len > 0); let let_mut = mut_if(len > 0);
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(_serializer, #type_name, #len)); let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
#(#serialize_stmts)* #(#serialize_stmts)*
_serde::ser::SerializeTupleStruct::end(__serde_state) _serde::ser::SerializeTupleStruct::end(__serde_state)
} }
@@ -166,7 +176,7 @@ fn serialize_struct(ident: &syn::Ident,
.fold(quote!(0), |sum, expr| quote!(#sum + #expr)); .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(_serializer, #type_name, #len)); let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
#(#serialize_fields)* #(#serialize_fields)*
_serde::ser::SerializeStruct::end(__serde_state) _serde::ser::SerializeStruct::end(__serde_state)
} }
@@ -292,7 +302,7 @@ fn serialize_externally_tagged_variant(ident: &syn::Ident,
Style::Unit => { Style::Unit => {
quote_expr! { quote_expr! {
_serde::Serializer::serialize_unit_variant( _serde::Serializer::serialize_unit_variant(
_serializer, __serializer,
#type_name, #type_name,
#variant_index, #variant_index,
#variant_name, #variant_name,
@@ -308,7 +318,7 @@ fn serialize_externally_tagged_variant(ident: &syn::Ident,
quote_expr! { quote_expr! {
_serde::Serializer::serialize_newtype_variant( _serde::Serializer::serialize_newtype_variant(
_serializer, __serializer,
#type_name, #type_name,
#variant_index, #variant_index,
#variant_name, #variant_name,
@@ -355,7 +365,7 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident,
Style::Unit => { Style::Unit => {
quote_block! { quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct( let mut __struct = try!(_serde::Serializer::serialize_struct(
_serializer, #type_name, 1)); __serializer, #type_name, 1));
try!(_serde::ser::SerializeStruct::serialize_field( try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)); &mut __struct, #tag, #variant_name));
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
@@ -370,7 +380,7 @@ fn serialize_internally_tagged_variant(ident: &syn::Ident,
quote_expr! { quote_expr! {
_serde::ser::private::serialize_tagged_newtype( _serde::ser::private::serialize_tagged_newtype(
_serializer, __serializer,
#enum_ident_str, #enum_ident_str,
#variant_ident_str, #variant_ident_str,
#tag, #tag,
@@ -407,7 +417,7 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident,
Style::Unit => { Style::Unit => {
return quote_block! { return quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct( let mut __struct = try!(_serde::Serializer::serialize_struct(
_serializer, #type_name, 1)); __serializer, #type_name, 1));
try!(_serde::ser::SerializeStruct::serialize_field( try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)); &mut __struct, #tag, #variant_name));
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
@@ -421,7 +431,7 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident,
} }
quote_expr! { quote_expr! {
_serde::Serialize::serialize(#field_expr, _serializer) _serde::Serialize::serialize(#field_expr, __serializer)
} }
} }
Style::Tuple => { Style::Tuple => {
@@ -468,7 +478,7 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident,
} }
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause { impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, _serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer where __S: _serde::Serializer
{ {
let (#(#fields_ident,)*) = self.data; let (#(#fields_ident,)*) = self.data;
@@ -477,7 +487,7 @@ fn serialize_adjacently_tagged_variant(ident: &syn::Ident,
} }
let mut __struct = try!(_serde::Serializer::serialize_struct( let mut __struct = try!(_serde::Serializer::serialize_struct(
_serializer, #type_name, 2)); __serializer, #type_name, 2));
try!(_serde::ser::SerializeStruct::serialize_field( try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)); &mut __struct, #tag, #variant_name));
try!(_serde::ser::SerializeStruct::serialize_field( try!(_serde::ser::SerializeStruct::serialize_field(
@@ -497,7 +507,7 @@ fn serialize_untagged_variant(ident: &syn::Ident,
match variant.style { match variant.style {
Style::Unit => { Style::Unit => {
quote_expr! { quote_expr! {
_serde::Serializer::serialize_unit(_serializer) _serde::Serializer::serialize_unit(__serializer)
} }
} }
Style::Newtype => { Style::Newtype => {
@@ -508,7 +518,7 @@ fn serialize_untagged_variant(ident: &syn::Ident,
} }
quote_expr! { quote_expr! {
_serde::Serialize::serialize(#field_expr, _serializer) _serde::Serialize::serialize(#field_expr, __serializer)
} }
} }
Style::Tuple => { Style::Tuple => {
@@ -556,7 +566,7 @@ fn serialize_tuple_variant(context: TupleVariant,
TupleVariant::ExternallyTagged { type_name, variant_index, variant_name } => { TupleVariant::ExternallyTagged { type_name, variant_index, variant_name } => {
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant( let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant(
_serializer, __serializer,
#type_name, #type_name,
#variant_index, #variant_index,
#variant_name, #variant_name,
@@ -568,7 +578,7 @@ fn serialize_tuple_variant(context: TupleVariant,
TupleVariant::Untagged => { TupleVariant::Untagged => {
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple( let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple(
_serializer, __serializer,
#len)); #len));
#(#serialize_stmts)* #(#serialize_stmts)*
_serde::ser::SerializeTuple::end(__serde_state) _serde::ser::SerializeTuple::end(__serde_state)
@@ -622,7 +632,7 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>,
StructVariant::ExternallyTagged { variant_index, variant_name } => { StructVariant::ExternallyTagged { variant_index, variant_name } => {
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant( let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant(
_serializer, __serializer,
#name, #name,
#variant_index, #variant_index,
#variant_name, #variant_name,
@@ -635,7 +645,7 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>,
StructVariant::InternallyTagged { tag, variant_name } => { StructVariant::InternallyTagged { tag, variant_name } => {
quote_block! { quote_block! {
let mut __serde_state = try!(_serde::Serializer::serialize_struct( let mut __serde_state = try!(_serde::Serializer::serialize_struct(
_serializer, __serializer,
#name, #name,
#len + 1, #len + 1,
)); ));
@@ -651,7 +661,7 @@ fn serialize_struct_variant<'a>(context: StructVariant<'a>,
StructVariant::Untagged => { StructVariant::Untagged => {
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct( let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(
_serializer, __serializer,
#name, #name,
#len, #len,
)); ));
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "0.9.11" version = "0.9.15"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@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"
+1 -1
View File
@@ -5,7 +5,7 @@ authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
publish = false publish = false
[features] [features]
unstable-testing = ["compiletest_rs"] unstable = ["serde/unstable", "compiletest_rs"]
[dev-dependencies] [dev-dependencies]
fnv = "1.0" fnv = "1.0"
+2 -1
View File
@@ -1,7 +1,8 @@
#![feature(lang_items, start, libc)] #![feature(lang_items, start, libc, compiler_builtins_lib)]
#![no_std] #![no_std]
extern crate libc; extern crate libc;
extern crate compiler_builtins;
#[start] #[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize { fn start(_argc: isize, _argv: *const *const u8) -> isize {
@@ -0,0 +1,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(from = "Option<T")] //~^ HELP: failed to parse type: from = "Option<T"
enum TestOne {
Testing,
One,
Two,
Three,
}
@@ -0,0 +1,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(into = "Option<T")] //~^ HELP: failed to parse type: into = "Option<T"
enum TestOne {
Testing,
One,
Two,
Three,
}
+1 -1
View File
@@ -1,4 +1,4 @@
#![cfg(feature = "unstable-testing")] #![cfg(feature = "unstable")]
extern crate compiletest_rs as compiletest; extern crate compiletest_rs as compiletest;
+80
View File
@@ -977,3 +977,83 @@ fn test_invalid_length_enum() {
Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()), Error::Message("invalid length 1, expected tuple of 2 elements".to_owned()),
); );
} }
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(into="EnumToU32", from="EnumToU32")]
struct StructFromEnum(Option<u32>);
impl Into<EnumToU32> for StructFromEnum {
fn into(self) -> EnumToU32 {
match self {
StructFromEnum(v) => v.into()
}
}
}
impl From<EnumToU32> for StructFromEnum {
fn from(v: EnumToU32) -> Self {
StructFromEnum(v.into())
}
}
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
#[serde(into="Option<u32>", from="Option<u32>")]
enum EnumToU32 {
One,
Two,
Three,
Four,
Nothing
}
impl Into<Option<u32>> for EnumToU32 {
fn into(self) -> Option<u32> {
match self {
EnumToU32::One => Some(1),
EnumToU32::Two => Some(2),
EnumToU32::Three => Some(3),
EnumToU32::Four => Some(4),
EnumToU32::Nothing => None
}
}
}
impl From<Option<u32>> for EnumToU32 {
fn from(v: Option<u32>) -> Self {
match v {
Some(1) => EnumToU32::One,
Some(2) => EnumToU32::Two,
Some(3) => EnumToU32::Three,
Some(4) => EnumToU32::Four,
_ => EnumToU32::Nothing
}
}
}
#[test]
fn test_from_into_traits() {
assert_ser_tokens::<EnumToU32>(&EnumToU32::One,
&[Token::Option(true),
Token::U32(1)
]
);
assert_ser_tokens::<EnumToU32>(&EnumToU32::Nothing,
&[Token::Option(false)]
);
assert_de_tokens::<EnumToU32>(&EnumToU32::Two,
&[Token::Option(true),
Token::U32(2)
]
);
assert_ser_tokens::<StructFromEnum>(&StructFromEnum(Some(5)),
&[Token::Option(false)]
);
assert_ser_tokens::<StructFromEnum>(&StructFromEnum(None),
&[Token::Option(false)]
);
assert_de_tokens::<StructFromEnum>(&StructFromEnum(Some(2)),
&[Token::Option(true),
Token::U32(2)
]
);
}
+108 -2
View File
@@ -1,3 +1,5 @@
#![cfg_attr(feature = "unstable", feature(into_boxed_c_str))]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
@@ -6,7 +8,10 @@ use std::net;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::Duration; use std::time::Duration;
use std::default::Default; use std::default::Default;
use std::ffi::CString; use std::ffi::{CString, OsString};
#[cfg(feature = "unstable")]
use std::ffi::CStr;
extern crate serde; extern crate serde;
use serde::Deserialize; use serde::Deserialize;
@@ -863,6 +868,28 @@ declare_tests! {
Token::SeqEnd, Token::SeqEnd,
], ],
} }
test_range {
1u32..2u32 => &[
Token::StructStart("Range", 2),
Token::StructSep,
Token::Str("start"),
Token::U32(1),
Token::StructSep,
Token::Str("end"),
Token::U32(2),
Token::StructEnd,
],
1u32..2u32 => &[
Token::SeqStart(Some(2)),
Token::SeqSep,
Token::U64(1),
Token::SeqSep,
Token::U64(2),
Token::SeqEnd,
],
}
test_net_ipv4addr { test_net_ipv4addr {
"1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => &[Token::Str("1.2.3.4")], "1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => &[Token::Str("1.2.3.4")],
} }
@@ -886,15 +913,94 @@ declare_tests! {
} }
} }
#[cfg(unix)]
#[test]
fn test_osstring() {
use std::os::unix::ffi::OsStringExt;
let value = OsString::from_vec(vec![1, 2, 3]);
let tokens = [
Token::EnumStart("OsString"),
Token::Str("Unix"),
Token::SeqStart(Some(2)),
Token::SeqSep,
Token::U8(1),
Token::SeqSep,
Token::U8(2),
Token::SeqSep,
Token::U8(3),
Token::SeqEnd,
];
assert_de_tokens(&value, &tokens);
assert_de_tokens_ignore(&tokens);
}
#[cfg(windows)]
#[test]
fn test_osstring() {
use std::os::windows::ffi::OsStringExt;
let value = OsString::from_wide(&[1, 2, 3]);
let tokens = [
Token::EnumStart("OsString"),
Token::Str("Windows"),
Token::SeqStart(Some(2)),
Token::SeqSep,
Token::U16(1),
Token::SeqSep,
Token::U16(2),
Token::SeqSep,
Token::U16(3),
Token::SeqEnd,
];
assert_de_tokens(&value, &tokens);
assert_de_tokens_ignore(&tokens);
}
#[cfg(feature = "unstable")]
#[test]
fn test_cstr() {
assert_de_tokens::<Box<CStr>>(&CString::new("abc").unwrap().into_boxed_c_str(),
&[Token::Bytes(b"abc")]);
}
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[test] #[test]
fn test_net_ipaddr() { fn test_net_ipaddr() {
assert_de_tokens( assert_de_tokens(
"1.2.3.4".parse::<net::IpAddr>().unwrap(), &"1.2.3.4".parse::<net::IpAddr>().unwrap(),
&[Token::Str("1.2.3.4")], &[Token::Str("1.2.3.4")],
); );
} }
#[cfg(feature = "unstable")]
#[test]
fn test_cstr_internal_null() {
assert_de_tokens_error::<Box<CStr>>(
&[
Token::Bytes(b"a\0c"),
],
Error::Message("nul byte found in provided data at position: 1".into())
);
}
#[cfg(feature = "unstable")]
#[test]
fn test_cstr_internal_null_end() {
assert_de_tokens_error::<Box<CStr>>(
&[
Token::Bytes(b"ac\0"),
],
Error::Message("nul byte found in provided data at position: 2".into())
);
}
declare_error_tests! { declare_error_tests! {
test_unknown_field<StructDenyUnknown> { test_unknown_field<StructDenyUnknown> {
&[ &[
+11 -11
View File
@@ -2,7 +2,7 @@
// successfully when there are a variety of generics and non-(de)serializable // successfully when there are a variety of generics and non-(de)serializable
// types involved. // types involved.
#![cfg_attr(feature = "unstable-testing", feature(non_ascii_idents))] #![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
@@ -220,8 +220,8 @@ fn test_gen() {
} }
assert::<EmptyEnumVariant>(); assert::<EmptyEnumVariant>();
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
struct NonAsciiIdents { struct NonAsciiIdents {
σ: f64 σ: f64
} }
@@ -246,12 +246,12 @@ fn test_gen() {
f: u8, f: u8,
} }
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
struct EmptyTuple(); struct EmptyTuple();
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
struct EmptyTupleDenyUnknown(); struct EmptyTupleDenyUnknown();
@@ -276,8 +276,8 @@ fn test_gen() {
Variant, Variant,
} }
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
enum EmptyVariants { enum EmptyVariants {
Braced {}, Braced {},
Tuple(), Tuple(),
@@ -288,8 +288,8 @@ fn test_gen() {
TupleSkip(#[serde(skip_deserializing)] u8), TupleSkip(#[serde(skip_deserializing)] u8),
} }
#[cfg(feature = "unstable-testing")] #[cfg(feature = "unstable")]
#[cfg_attr(feature = "unstable-testing", derive(Serialize, Deserialize))] #[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
enum EmptyVariantsDenyUnknown { enum EmptyVariantsDenyUnknown {
Braced {}, Braced {},
+15 -47
View File
@@ -21,9 +21,6 @@ use self::serde_test::{
extern crate fnv; extern crate fnv;
use self::fnv::FnvHasher; use self::fnv::FnvHasher;
#[cfg(feature = "unstable")]
use serde::ser::iterator;
#[macro_use] #[macro_use]
mod macros; mod macros;
@@ -369,6 +366,19 @@ declare_tests! {
Token::StructEnd, Token::StructEnd,
], ],
} }
test_range {
1u32..2u32 => &[
Token::StructStart("Range", 2),
Token::StructSep,
Token::Str("start"),
Token::U32(1),
Token::StructSep,
Token::Str("end"),
Token::U32(2),
Token::StructEnd,
],
}
test_net_ipv4addr { test_net_ipv4addr {
"1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => &[Token::Str("1.2.3.4")], "1.2.3.4".parse::<net::Ipv4Addr>().unwrap() => &[Token::Str("1.2.3.4")],
} }
@@ -402,59 +412,17 @@ declare_tests! {
} }
} }
#[cfg(feature = "unstable")]
#[test]
fn test_iterator() {
assert_ser_tokens(iterator([0; 0].iter()), &[
Token::SeqStart(Some(0)),
Token::SeqEnd,
]);
assert_ser_tokens(iterator([1, 2, 3].iter()), &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
]);
assert_ser_tokens(iterator([1, 2, 3].iter().map(|x| x * 2)), &[
Token::SeqStart(Some(3)),
Token::SeqSep,
Token::I32(2),
Token::SeqSep,
Token::I32(4),
Token::SeqSep,
Token::I32(6),
Token::SeqEnd,
]);
assert_ser_tokens(iterator([1, 2, 3].iter().filter(|&x| x % 2 != 0)), &[
Token::SeqStart(None),
Token::SeqSep,
Token::I32(1),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
]);
}
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[test] #[test]
fn test_net_ipaddr() { fn test_net_ipaddr() {
assert_ser_tokens( assert_ser_tokens(
"1.2.3.4".parse::<net::IpAddr>().unwrap(), &"1.2.3.4".parse::<net::IpAddr>().unwrap(),
&[Token::Str("1.2.3.4")], &[Token::Str("1.2.3.4")],
); );
} }
#[test] #[test]
#[cfg(unix)]
fn test_cannot_serialize_paths() { fn test_cannot_serialize_paths() {
let path = unsafe { let path = unsafe {
str::from_utf8_unchecked(b"Hello \xF0\x90\x80World") str::from_utf8_unchecked(b"Hello \xF0\x90\x80World")
+19
View File
@@ -0,0 +1,19 @@
#[macro_use]
extern crate serde_derive;
extern crate serde;
use serde::Deserialize;
use serde::de::value::{self, ValueDeserializer};
#[test]
fn test_u32_to_enum() {
#[derive(Deserialize, Debug, PartialEq)]
enum E {
A,
B,
}
let deserializer = ValueDeserializer::<value::Error>::into_deserializer(1u32);
let e: E = E::deserialize(deserializer).unwrap();
assert_eq!(E::B, e);
}
+7 -2
View File
@@ -10,6 +10,11 @@ channel() {
pwd pwd
(set -x; cargo "$@") (set -x; cargo "$@")
fi fi
elif [ -n "${APPVEYOR}" ]; then
if [ "${APPVEYOR_RUST_CHANNEL}" = "${CHANNEL}" ]; then
pwd
(set -x; cargo "$@")
fi
else else
pwd pwd
(set -x; cargo "+${CHANNEL}" "$@") (set -x; cargo "+${CHANNEL}" "$@")
@@ -30,7 +35,7 @@ if [ -n "${CLIPPY}" ]; then
cargo clippy --features unstable-testing -- -Dclippy cargo clippy --features unstable-testing -- -Dclippy
cd "$DIR/test_suite" cd "$DIR/test_suite"
cargo clippy --features unstable-testing -- -Dclippy cargo clippy --features unstable -- -Dclippy
cd "$DIR/test_suite/no_std" cd "$DIR/test_suite/no_std"
cargo clippy -- -Dclippy cargo clippy -- -Dclippy
@@ -46,7 +51,7 @@ else
cd "$DIR/test_suite/deps" cd "$DIR/test_suite/deps"
channel build channel build
cd "$DIR/test_suite" cd "$DIR/test_suite"
channel test --features unstable-testing channel test --features unstable
cd "$DIR/test_suite/no_std" cd "$DIR/test_suite/no_std"
channel build channel build