mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-25 12:47:56 +00:00
Compare commits
35 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9338c4f1b9 | |||
| 28d67f4172 | |||
| 2401ae61a8 | |||
| 57d3fce0c6 | |||
| a020cceed8 | |||
| 49e985eb90 | |||
| 63def96c66 | |||
| 2fea8c9c28 | |||
| 2c984980a0 | |||
| 36f07912b8 | |||
| 7222cf7514 | |||
| 08c59a2e0e | |||
| 4a0bf4de65 | |||
| 95ffca9bbe | |||
| 5e47c87ba0 | |||
| c6d5d9be14 | |||
| d63d09f4db | |||
| de6d00c306 | |||
| 5bda95ba81 | |||
| 36641e7b81 | |||
| 6eca34c45c | |||
| 7efa0153b0 | |||
| 8dba87661b | |||
| 17fb4cb503 | |||
| 5bd0386b8e | |||
| 8b484c9703 | |||
| a16f07858b | |||
| 133d117bf4 | |||
| e7f3a80867 | |||
| f8c3d225a3 | |||
| 6d40d9e8ec | |||
| c91fca19e1 | |||
| f13a805530 | |||
| 54802983b8 | |||
| f430d9d1c8 |
+1
-1
@@ -1,8 +1,8 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
language: rust
|
language: rust
|
||||||
rust:
|
rust:
|
||||||
- 1.10.0
|
|
||||||
- 1.11.0
|
- 1.11.0
|
||||||
|
- 1.12.0
|
||||||
- stable
|
- stable
|
||||||
- beta
|
- beta
|
||||||
- nightly
|
- nightly
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ You may be looking for:
|
|||||||
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
|
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
|
||||||
- [Examples](https://serde.rs/examples.html)
|
- [Examples](https://serde.rs/examples.html)
|
||||||
- [API documentation](https://docs.serde.rs/serde/)
|
- [API documentation](https://docs.serde.rs/serde/)
|
||||||
|
- [Release notes](https://github.com/serde-rs/serde/releases)
|
||||||
|
|
||||||
## Serde in action
|
## Serde in action
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "0.8.16"
|
version = "0.8.21"
|
||||||
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"
|
||||||
|
|||||||
@@ -283,6 +283,12 @@ impl Visitor for StringVisitor {
|
|||||||
Ok(v)
|
Ok(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_unit<E>(&mut self) -> Result<String, E>
|
||||||
|
where E: Error,
|
||||||
|
{
|
||||||
|
Ok(String::new())
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<String, E>
|
fn visit_bytes<E>(&mut self, v: &[u8]) -> Result<String, E>
|
||||||
where E: Error,
|
where E: Error,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_codegen"
|
name = "serde_codegen"
|
||||||
version = "0.8.16"
|
version = "0.8.21"
|
||||||
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 to auto-generate implementations for the serde framework"
|
description = "Macros to auto-generate implementations for the serde framework"
|
||||||
@@ -22,9 +22,8 @@ with-syn = []
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "^0.*", optional = true }
|
||||||
post-expansion = "0.1.0"
|
quote = "0.3.8"
|
||||||
quote = "0.3"
|
serde_codegen_internals = { version = "=0.11.3", default-features = false, path = "../serde_codegen_internals" }
|
||||||
serde_codegen_internals = { version = "=0.10.0", default-features = false, path = "../serde_codegen_internals" }
|
syn = { version = "0.10", features = ["aster", "visit"] }
|
||||||
syn = { version = "0.9", features = ["aster", "visit"] }
|
syntex = { version = "^0.52.0", optional = true }
|
||||||
syntex = { version = "^0.46.0", optional = true }
|
syntex_syntax = { version = "^0.52.0", optional = true }
|
||||||
syntex_syntax = { version = "^0.46.0", optional = true }
|
|
||||||
|
|||||||
@@ -496,6 +496,7 @@ fn deserialize_item_enum(
|
|||||||
|
|
||||||
let variant_visitor = deserialize_field_visitor(
|
let variant_visitor = deserialize_field_visitor(
|
||||||
variants.iter()
|
variants.iter()
|
||||||
|
.filter(|variant| !variant.attrs.skip_deserializing())
|
||||||
.map(|variant| variant.attrs.name().deserialize_name())
|
.map(|variant| variant.attrs.name().deserialize_name())
|
||||||
.collect(),
|
.collect(),
|
||||||
item_attrs,
|
item_attrs,
|
||||||
@@ -518,7 +519,7 @@ fn deserialize_item_enum(
|
|||||||
|
|
||||||
// Match arms to extract a variant from a string
|
// Match arms to extract a variant from a string
|
||||||
let mut variant_arms = vec![];
|
let mut variant_arms = vec![];
|
||||||
for (i, variant) in variants.iter().enumerate() {
|
for (i, variant) in variants.iter().filter(|variant| !variant.attrs.skip_deserializing()).enumerate() {
|
||||||
let variant_name = aster::id(format!("__field{}", i));
|
let variant_name = aster::id(format!("__field{}", i));
|
||||||
let variant_name = quote!(__Field::#variant_name);
|
let variant_name = quote!(__Field::#variant_name);
|
||||||
|
|
||||||
|
|||||||
+28
-104
@@ -2,7 +2,6 @@
|
|||||||
#![cfg_attr(feature = "clippy", feature(plugin))]
|
#![cfg_attr(feature = "clippy", feature(plugin))]
|
||||||
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
#![cfg_attr(feature = "clippy", allow(too_many_arguments))]
|
||||||
#![cfg_attr(feature = "clippy", allow(used_underscore_binding))]
|
#![cfg_attr(feature = "clippy", allow(used_underscore_binding))]
|
||||||
#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private, plugin))]
|
|
||||||
|
|
||||||
// The `quote!` macro requires deep recursion.
|
// The `quote!` macro requires deep recursion.
|
||||||
#![recursion_limit = "192"]
|
#![recursion_limit = "192"]
|
||||||
@@ -16,26 +15,13 @@ extern crate syntex;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate syntex_syntax as syntax;
|
extern crate syntex_syntax as syntax;
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
#[macro_use]
|
|
||||||
extern crate syntax;
|
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
extern crate rustc_plugin;
|
|
||||||
|
|
||||||
extern crate syn;
|
extern crate syn;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate quote;
|
extern crate quote;
|
||||||
|
|
||||||
#[cfg(feature = "with-syn")]
|
|
||||||
extern crate post_expansion;
|
|
||||||
|
|
||||||
#[cfg(feature = "with-syntex")]
|
#[cfg(feature = "with-syntex")]
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
use syntax::feature_gate::AttributeType;
|
|
||||||
|
|
||||||
mod bound;
|
mod bound;
|
||||||
mod de;
|
mod de;
|
||||||
mod ser;
|
mod ser;
|
||||||
@@ -52,11 +38,11 @@ fn syntex_registry() -> syntex::Registry {
|
|||||||
|
|
||||||
impl fold::Folder for StripAttributeFolder {
|
impl fold::Folder for StripAttributeFolder {
|
||||||
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
|
||||||
match attr.node.value.node {
|
if attr.value.name == "serde" {
|
||||||
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; }
|
if let ast::MetaItemKind::List(..) = attr.value.node {
|
||||||
_ => {}
|
return None;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(attr)
|
Some(attr)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,8 +59,8 @@ fn syntex_registry() -> syntex::Registry {
|
|||||||
reg.add_attr("feature(custom_derive)");
|
reg.add_attr("feature(custom_derive)");
|
||||||
reg.add_attr("feature(custom_attribute)");
|
reg.add_attr("feature(custom_attribute)");
|
||||||
|
|
||||||
reg.add_decorator("derive_Serialize", expand_derive_serialize);
|
reg.add_decorator("derive_Serialize", shim::expand_derive_serialize);
|
||||||
reg.add_decorator("derive_Deserialize", expand_derive_deserialize);
|
reg.add_decorator("derive_Deserialize", shim::expand_derive_deserialize);
|
||||||
|
|
||||||
reg.add_post_expansion_pass(strip_attributes);
|
reg.add_post_expansion_pass(strip_attributes);
|
||||||
|
|
||||||
@@ -107,24 +93,9 @@ pub fn expand<S, D>(src: S, dst: D) -> Result<(), syntex::Error>
|
|||||||
syntex::with_extra_stack(expand_thread)
|
syntex::with_extra_stack(expand_thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "with-syntex"))]
|
|
||||||
pub fn register(reg: &mut rustc_plugin::Registry) {
|
|
||||||
reg.register_syntax_extension(
|
|
||||||
syntax::parse::token::intern("derive_Serialize"),
|
|
||||||
syntax::ext::base::MultiDecorator(
|
|
||||||
Box::new(expand_derive_serialize)));
|
|
||||||
|
|
||||||
reg.register_syntax_extension(
|
|
||||||
syntax::parse::token::intern("derive_Deserialize"),
|
|
||||||
syntax::ext::base::MultiDecorator(
|
|
||||||
Box::new(expand_derive_deserialize)));
|
|
||||||
|
|
||||||
reg.register_attribute("serde".to_owned(), AttributeType::Normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! shim {
|
macro_rules! shim {
|
||||||
($name:ident $pkg:ident :: $func:ident) => {
|
($name:ident $pkg:ident :: $func:ident) => {
|
||||||
fn $func(
|
pub fn $func(
|
||||||
cx: &mut ::syntax::ext::base::ExtCtxt,
|
cx: &mut ::syntax::ext::base::ExtCtxt,
|
||||||
span: ::syntax::codemap::Span,
|
span: ::syntax::codemap::Span,
|
||||||
meta_item: &::syntax::ast::MetaItem,
|
meta_item: &::syntax::ast::MetaItem,
|
||||||
@@ -147,11 +118,10 @@ macro_rules! shim {
|
|||||||
struct MarkSerdeAttributesUsed;
|
struct MarkSerdeAttributesUsed;
|
||||||
impl visit::Visitor for MarkSerdeAttributesUsed {
|
impl visit::Visitor for MarkSerdeAttributesUsed {
|
||||||
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
fn visit_attribute(&mut self, attr: &ast::Attribute) {
|
||||||
match attr.node.value.node {
|
if attr.value.name == "serde" {
|
||||||
ast::MetaItemKind::List(ref name, _) if name == "serde" => {
|
if let ast::MetaItemKind::List(..) = attr.value.node {
|
||||||
attr::mark_used(attr);
|
attr::mark_used(attr);
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,6 +130,7 @@ macro_rules! shim {
|
|||||||
use syntax::print::pprust;
|
use syntax::print::pprust;
|
||||||
let s = pprust::item_to_string(item);
|
let s = pprust::item_to_string(item);
|
||||||
|
|
||||||
|
use {syn, $pkg};
|
||||||
let syn_item = syn::parse_macro_input(&s).unwrap();
|
let syn_item = syn::parse_macro_input(&s).unwrap();
|
||||||
let expanded = match $pkg::$func(&syn_item) {
|
let expanded = match $pkg::$func(&syn_item) {
|
||||||
Ok(expanded) => expanded.to_string(),
|
Ok(expanded) => expanded.to_string(),
|
||||||
@@ -171,78 +142,31 @@ macro_rules! shim {
|
|||||||
|
|
||||||
use syntax::parse;
|
use syntax::parse;
|
||||||
let name = stringify!($name).to_string();
|
let name = stringify!($name).to_string();
|
||||||
let cfg = Vec::new();
|
|
||||||
let sess = cx.parse_sess;
|
let sess = cx.parse_sess;
|
||||||
let impl_item = parse::parse_item_from_source_str(name, expanded, cfg, sess);
|
let impl_item = parse::parse_item_from_source_str(name, expanded, sess);
|
||||||
push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
|
push(::syntax::ext::base::Annotatable::Item(impl_item.unwrap().unwrap()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
shim!(Serialize ser::expand_derive_serialize);
|
#[cfg(feature = "with-syntex")]
|
||||||
shim!(Deserialize de::expand_derive_deserialize);
|
mod shim {
|
||||||
|
shim!(Serialize ser::expand_derive_serialize);
|
||||||
|
shim!(Deserialize de::expand_derive_deserialize);
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "with-syn")]
|
#[cfg(feature = "with-syn")]
|
||||||
pub fn expand_single_item(item: &str) -> Result<String, String> {
|
#[doc(hidden)]
|
||||||
|
/// Not public API. Use the serde_derive crate.
|
||||||
|
pub fn expand_derive_serialize(item: &str) -> Result<quote::Tokens, String> {
|
||||||
let syn_item = syn::parse_macro_input(item).unwrap();
|
let syn_item = syn::parse_macro_input(item).unwrap();
|
||||||
let (ser, de, syn_item) = strip_serde_derives(syn_item);
|
ser::expand_derive_serialize(&syn_item)
|
||||||
let expanded_ser = if ser {
|
}
|
||||||
Some(try!(ser::expand_derive_serialize(&syn_item)))
|
|
||||||
} else {
|
#[cfg(feature = "with-syn")]
|
||||||
None
|
#[doc(hidden)]
|
||||||
};
|
/// Not public API. Use the serde_derive crate.
|
||||||
let expanded_de = if de {
|
pub fn expand_derive_deserialize(item: &str) -> Result<quote::Tokens, String> {
|
||||||
Some(try!(de::expand_derive_deserialize(&syn_item)))
|
let syn_item = syn::parse_macro_input(item).unwrap();
|
||||||
} else {
|
de::expand_derive_deserialize(&syn_item)
|
||||||
None::<quote::Tokens>
|
|
||||||
};
|
|
||||||
let syn_item = post_expansion::strip_attrs_later(syn_item, &["serde"], "serde");
|
|
||||||
return Ok(quote!(#expanded_ser #expanded_de #syn_item).to_string());
|
|
||||||
|
|
||||||
fn strip_serde_derives(item: syn::MacroInput) -> (bool, bool, syn::MacroInput) {
|
|
||||||
let mut ser = false;
|
|
||||||
let mut de = false;
|
|
||||||
let item = syn::MacroInput {
|
|
||||||
attrs: item.attrs.into_iter().flat_map(|attr| {
|
|
||||||
if attr.is_sugared_doc || attr.style != syn::AttrStyle::Outer {
|
|
||||||
return Some(attr);
|
|
||||||
}
|
|
||||||
let (name, nested) = match attr.value {
|
|
||||||
syn::MetaItem::List(name, nested) => (name, nested),
|
|
||||||
_ => return Some(attr)
|
|
||||||
};
|
|
||||||
if name != "derive" {
|
|
||||||
return Some(syn::Attribute {
|
|
||||||
style: syn::AttrStyle::Outer,
|
|
||||||
value: syn::MetaItem::List(name, nested),
|
|
||||||
is_sugared_doc: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
let rest: Vec<_> = nested.into_iter().filter(|nested| {
|
|
||||||
match *nested {
|
|
||||||
syn::MetaItem::Word(ref word) if word == "Serialize" => {
|
|
||||||
ser = true;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
syn::MetaItem::Word(ref word) if word == "Deserialize" => {
|
|
||||||
de = true;
|
|
||||||
false
|
|
||||||
}
|
|
||||||
_ => true,
|
|
||||||
}
|
|
||||||
}).collect();
|
|
||||||
if rest.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(syn::Attribute {
|
|
||||||
style: syn::AttrStyle::Outer,
|
|
||||||
value: syn::MetaItem::List(name, rest),
|
|
||||||
is_sugared_doc: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}).collect(),
|
|
||||||
..item
|
|
||||||
};
|
|
||||||
(ser, de, item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-67
@@ -256,76 +256,80 @@ fn serialize_variant(
|
|||||||
let variant_ident = variant.ident.clone();
|
let variant_ident = variant.ident.clone();
|
||||||
let variant_name = variant.attrs.name().serialize_name();
|
let variant_name = variant.attrs.name().serialize_name();
|
||||||
|
|
||||||
match variant.style {
|
if variant.attrs.skip_serializing() {
|
||||||
Style::Unit => {
|
let skipped_msg = format!("The enum variant {}::{} cannot be serialized",
|
||||||
quote! {
|
type_ident, variant_ident);
|
||||||
#type_ident::#variant_ident =>
|
let skipped_err = quote! {
|
||||||
_serde::ser::Serializer::serialize_unit_variant(
|
Err(_serde::ser::Error::invalid_value(#skipped_msg))
|
||||||
_serializer,
|
};
|
||||||
#type_name,
|
let fields_pat = match variant.style {
|
||||||
#variant_index,
|
Style::Unit => quote!(),
|
||||||
#variant_name,
|
Style::Newtype | Style::Tuple => quote!( (..) ),
|
||||||
),
|
Style::Struct => quote!( {..} ),
|
||||||
}
|
};
|
||||||
},
|
quote! {
|
||||||
Style::Newtype => {
|
#type_ident::#variant_ident #fields_pat => #skipped_err,
|
||||||
let block = serialize_newtype_variant(
|
|
||||||
type_name,
|
|
||||||
variant_index,
|
|
||||||
variant_name,
|
|
||||||
ty,
|
|
||||||
generics,
|
|
||||||
&variant.fields[0],
|
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#type_ident::#variant_ident(ref __simple_value) => #block,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Style::Tuple => {
|
|
||||||
let field_names: Vec<Tokens> = (0 .. variant.fields.len())
|
|
||||||
.map(|i| {
|
|
||||||
let id = aster::id(format!("__field{}", i));
|
|
||||||
quote!(ref #id)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let pat = quote!(#type_ident::#variant_ident(#(#field_names),*));
|
|
||||||
|
|
||||||
let block = serialize_tuple_variant(
|
|
||||||
type_name,
|
|
||||||
variant_index,
|
|
||||||
variant_name,
|
|
||||||
generics,
|
|
||||||
ty,
|
|
||||||
&variant.fields,
|
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
#pat => { #block }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Style::Struct => {
|
} else { // variant wasn't skipped
|
||||||
let fields = variant.fields.iter().map(|field| {
|
match variant.style {
|
||||||
let id = match field.ident {
|
Style::Unit => {
|
||||||
Some(ref name) => name.clone(),
|
quote! {
|
||||||
None => panic!("struct variant has unnamed fields"),
|
#type_ident::#variant_ident =>
|
||||||
};
|
_serde::ser::Serializer::serialize_unit_variant(
|
||||||
quote!(ref #id)
|
_serializer,
|
||||||
});
|
#type_name,
|
||||||
let pat = quote!(#type_ident::#variant_ident { #(#fields),* });
|
#variant_index,
|
||||||
|
#variant_name,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Style::Newtype => {
|
||||||
|
let block = serialize_newtype_variant(
|
||||||
|
type_name,
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
ty,
|
||||||
|
generics,
|
||||||
|
&variant.fields[0],
|
||||||
|
);
|
||||||
|
|
||||||
let block = serialize_struct_variant(
|
quote! {
|
||||||
variant_index,
|
#type_ident::#variant_ident(ref __simple_value) => #block,
|
||||||
variant_name,
|
}
|
||||||
generics,
|
},
|
||||||
ty,
|
Style::Tuple => {
|
||||||
&variant.fields,
|
let field_names = (0 .. variant.fields.len())
|
||||||
item_attrs,
|
.map(|i| aster::id(format!("__field{}", i)));
|
||||||
);
|
|
||||||
|
|
||||||
quote! {
|
let block = serialize_tuple_variant(
|
||||||
#pat => { #block }
|
type_name,
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
generics,
|
||||||
|
ty,
|
||||||
|
&variant.fields,
|
||||||
|
);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#type_ident::#variant_ident(#(ref #field_names),*) => { #block }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Style::Struct => {
|
||||||
|
let fields = variant.fields.iter()
|
||||||
|
.map(|f| f.ident.clone().expect("struct variant has unnamed fields"));
|
||||||
|
|
||||||
|
let block = serialize_struct_variant(
|
||||||
|
variant_index,
|
||||||
|
variant_name,
|
||||||
|
generics,
|
||||||
|
ty,
|
||||||
|
&variant.fields,
|
||||||
|
item_attrs,
|
||||||
|
);
|
||||||
|
|
||||||
|
quote! {
|
||||||
|
#type_ident::#variant_ident { #(ref #fields),* } => { #block }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_codegen_internals"
|
name = "serde_codegen_internals"
|
||||||
version = "0.10.0"
|
version = "0.11.3"
|
||||||
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."
|
||||||
@@ -15,4 +15,4 @@ unstable-testing = ["clippy"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clippy = { version = "^0.*", optional = true }
|
clippy = { version = "^0.*", optional = true }
|
||||||
syn = "0.9"
|
syn = "0.10"
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use Ctxt;
|
use Ctxt;
|
||||||
use syn;
|
use syn;
|
||||||
|
use syn::MetaItem::{List, NameValue, Word};
|
||||||
|
use syn::NestedMetaItem::{Literal, MetaItem};
|
||||||
|
|
||||||
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
|
// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
|
||||||
// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and
|
// are `attr::Item::from_ast`, `attr::Variant::from_ast`, and
|
||||||
@@ -105,7 +107,7 @@ impl Item {
|
|||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename="foo")]`
|
// Parse `#[serde(rename="foo")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "rename" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
|
||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_name.set(s.clone());
|
ser_name.set(s.clone());
|
||||||
de_name.set(s);
|
de_name.set(s);
|
||||||
@@ -113,7 +115,7 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "rename" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
|
||||||
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
||||||
ser_name.set_opt(ser);
|
ser_name.set_opt(ser);
|
||||||
de_name.set_opt(de);
|
de_name.set_opt(de);
|
||||||
@@ -121,12 +123,12 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(deny_unknown_fields)]`
|
// Parse `#[serde(deny_unknown_fields)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "deny_unknown_fields" => {
|
MetaItem(Word(ref name)) if name == "deny_unknown_fields" => {
|
||||||
deny_unknown_fields.set_true();
|
deny_unknown_fields.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound="D: Serialize")]`
|
// Parse `#[serde(bound="D: Serialize")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "bound" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
||||||
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_bound.set(where_predicates.clone());
|
ser_bound.set(where_predicates.clone());
|
||||||
de_bound.set(where_predicates);
|
de_bound.set(where_predicates);
|
||||||
@@ -134,17 +136,21 @@ impl Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "bound" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
|
||||||
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
||||||
ser_bound.set_opt(ser);
|
ser_bound.set_opt(ser);
|
||||||
de_bound.set_opt(de);
|
de_bound.set_opt(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde container attribute `{}`",
|
cx.error(format!("unknown serde container attribute `{}`",
|
||||||
meta_item.name()));
|
meta_item.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal(_) => {
|
||||||
|
cx.error(format!("unexpected literal in serde container attribute"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,18 +187,22 @@ impl Item {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Variant {
|
pub struct Variant {
|
||||||
name: Name,
|
name: Name,
|
||||||
|
skip_deserializing: bool,
|
||||||
|
skip_serializing: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Variant {
|
impl Variant {
|
||||||
pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
|
pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
|
||||||
let mut ser_name = Attr::none(cx, "rename");
|
let mut ser_name = Attr::none(cx, "rename");
|
||||||
let mut de_name = Attr::none(cx, "rename");
|
let mut de_name = Attr::none(cx, "rename");
|
||||||
|
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
|
||||||
|
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
|
||||||
|
|
||||||
for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
|
for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
|
||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename="foo")]`
|
// Parse `#[serde(rename="foo")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "rename" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
|
||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_name.set(s.clone());
|
ser_name.set(s.clone());
|
||||||
de_name.set(s);
|
de_name.set(s);
|
||||||
@@ -200,17 +210,29 @@ impl Variant {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "rename" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
|
||||||
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
||||||
ser_name.set_opt(ser);
|
ser_name.set_opt(ser);
|
||||||
de_name.set_opt(de);
|
de_name.set_opt(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Parse `#[serde(skip_deserializing)]`
|
||||||
|
MetaItem(Word(ref name)) if name == "skip_deserializing" => {
|
||||||
|
skip_deserializing.set_true();
|
||||||
|
}
|
||||||
|
// Parse `#[serde(skip_serializing)]`
|
||||||
|
MetaItem(Word(ref name)) if name == "skip_serializing" => {
|
||||||
|
skip_serializing.set_true();
|
||||||
|
}
|
||||||
|
|
||||||
_ => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde variant attribute `{}`",
|
cx.error(format!("unknown serde variant attribute `{}`",
|
||||||
meta_item.name()));
|
meta_item.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal(_) => {
|
||||||
|
cx.error(format!("unexpected literal in serde variant attribute"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -220,12 +242,22 @@ impl Variant {
|
|||||||
serialize: ser_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
serialize: ser_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
||||||
deserialize: de_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
deserialize: de_name.get().unwrap_or_else(|| variant.ident.to_string()),
|
||||||
},
|
},
|
||||||
|
skip_deserializing: skip_deserializing.get(),
|
||||||
|
skip_serializing: skip_serializing.get(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &Name {
|
pub fn name(&self) -> &Name {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn skip_deserializing(&self) -> bool {
|
||||||
|
self.skip_deserializing
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn skip_serializing(&self) -> bool {
|
||||||
|
self.skip_serializing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents field attribute information
|
/// Represents field attribute information
|
||||||
@@ -278,7 +310,7 @@ impl Field {
|
|||||||
for meta_item in meta_items {
|
for meta_item in meta_items {
|
||||||
match meta_item {
|
match meta_item {
|
||||||
// Parse `#[serde(rename="foo")]`
|
// Parse `#[serde(rename="foo")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "rename" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
|
||||||
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_name.set(s.clone());
|
ser_name.set(s.clone());
|
||||||
de_name.set(s);
|
de_name.set(s);
|
||||||
@@ -286,7 +318,7 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
// Parse `#[serde(rename(serialize="foo", deserialize="bar"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "rename" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "rename" => {
|
||||||
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
if let Ok((ser, de)) = get_renames(cx, meta_items) {
|
||||||
ser_name.set_opt(ser);
|
ser_name.set_opt(ser);
|
||||||
de_name.set_opt(de);
|
de_name.set_opt(de);
|
||||||
@@ -294,50 +326,50 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(default)]`
|
// Parse `#[serde(default)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "default" => {
|
MetaItem(Word(ref name)) if name == "default" => {
|
||||||
default.set(FieldDefault::Default);
|
default.set(FieldDefault::Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(default="...")]`
|
// Parse `#[serde(default="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "default" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "default" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
default.set(FieldDefault::Path(path));
|
default.set(FieldDefault::Path(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_serializing)]`
|
// Parse `#[serde(skip_serializing)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "skip_serializing" => {
|
MetaItem(Word(ref name)) if name == "skip_serializing" => {
|
||||||
skip_serializing.set_true();
|
skip_serializing.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_deserializing)]`
|
// Parse `#[serde(skip_deserializing)]`
|
||||||
syn::MetaItem::Word(ref name) if name == "skip_deserializing" => {
|
MetaItem(Word(ref name)) if name == "skip_deserializing" => {
|
||||||
skip_deserializing.set_true();
|
skip_deserializing.set_true();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(skip_serializing_if="...")]`
|
// Parse `#[serde(skip_serializing_if="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "skip_serializing_if" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "skip_serializing_if" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
skip_serializing_if.set(path);
|
skip_serializing_if.set(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(serialize_with="...")]`
|
// Parse `#[serde(serialize_with="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "serialize_with" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
serialize_with.set(path);
|
serialize_with.set(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(deserialize_with="...")]`
|
// Parse `#[serde(deserialize_with="...")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "deserialize_with" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
|
||||||
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
|
||||||
deserialize_with.set(path);
|
deserialize_with.set(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound="D: Serialize")]`
|
// Parse `#[serde(bound="D: Serialize")]`
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "bound" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
|
||||||
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
if let Ok(where_predicates) = parse_lit_into_where(cx, name.as_ref(), name.as_ref(), lit) {
|
||||||
ser_bound.set(where_predicates.clone());
|
ser_bound.set(where_predicates.clone());
|
||||||
de_bound.set(where_predicates);
|
de_bound.set(where_predicates);
|
||||||
@@ -345,17 +377,21 @@ impl Field {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
// Parse `#[serde(bound(serialize="D: Serialize", deserialize="D: Deserialize"))]`
|
||||||
syn::MetaItem::List(ref name, ref meta_items) if name == "bound" => {
|
MetaItem(List(ref name, ref meta_items)) if name == "bound" => {
|
||||||
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
if let Ok((ser, de)) = get_where_predicates(cx, meta_items) {
|
||||||
ser_bound.set_opt(ser);
|
ser_bound.set_opt(ser);
|
||||||
de_bound.set_opt(de);
|
de_bound.set_opt(de);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
MetaItem(ref meta_item) => {
|
||||||
cx.error(format!("unknown serde field attribute `{}`",
|
cx.error(format!("unknown serde field attribute `{}`",
|
||||||
meta_item.name()));
|
meta_item.name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Literal(_) => {
|
||||||
|
cx.error(format!("unexpected literal in serde field attribute"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +460,7 @@ type SerAndDe<T> = (Option<T>, Option<T>);
|
|||||||
fn get_ser_and_de<T, F>(
|
fn get_ser_and_de<T, F>(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
attr_name: &'static str,
|
attr_name: &'static str,
|
||||||
items: &[syn::MetaItem],
|
items: &[syn::NestedMetaItem],
|
||||||
f: F
|
f: F
|
||||||
) -> Result<SerAndDe<T>, ()>
|
) -> Result<SerAndDe<T>, ()>
|
||||||
where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
|
where F: Fn(&Ctxt, &str, &str, &syn::Lit) -> Result<T, ()>,
|
||||||
@@ -434,13 +470,13 @@ fn get_ser_and_de<T, F>(
|
|||||||
|
|
||||||
for item in items {
|
for item in items {
|
||||||
match *item {
|
match *item {
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "serialize" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "serialize" => {
|
||||||
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
||||||
ser_item.set(v);
|
ser_item.set(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syn::MetaItem::NameValue(ref name, ref lit) if name == "deserialize" => {
|
MetaItem(NameValue(ref name, ref lit)) if name == "deserialize" => {
|
||||||
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
if let Ok(v) = f(cx, attr_name, name.as_ref(), lit) {
|
||||||
de_item.set(v);
|
de_item.set(v);
|
||||||
}
|
}
|
||||||
@@ -459,21 +495,21 @@ fn get_ser_and_de<T, F>(
|
|||||||
|
|
||||||
fn get_renames(
|
fn get_renames(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
items: &[syn::MetaItem],
|
items: &[syn::NestedMetaItem],
|
||||||
) -> Result<SerAndDe<String>, ()> {
|
) -> Result<SerAndDe<String>, ()> {
|
||||||
get_ser_and_de(cx, "rename", items, get_string_from_lit)
|
get_ser_and_de(cx, "rename", items, get_string_from_lit)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_where_predicates(
|
fn get_where_predicates(
|
||||||
cx: &Ctxt,
|
cx: &Ctxt,
|
||||||
items: &[syn::MetaItem],
|
items: &[syn::NestedMetaItem],
|
||||||
) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
|
) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
|
||||||
get_ser_and_de(cx, "bound", items, parse_lit_into_where)
|
get_ser_and_de(cx, "bound", items, parse_lit_into_where)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::MetaItem>> {
|
pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMetaItem>> {
|
||||||
match attr.value {
|
match attr.value {
|
||||||
syn::MetaItem::List(ref name, ref items) if name == "serde" => {
|
List(ref name, ref items) if name == "serde" => {
|
||||||
Some(items.iter().cloned().collect())
|
Some(items.iter().cloned().collect())
|
||||||
}
|
}
|
||||||
_ => None
|
_ => None
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "0.8.16"
|
version = "0.8.21"
|
||||||
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)]"
|
||||||
@@ -14,11 +14,8 @@ include = ["Cargo.toml", "src/**/*.rs"]
|
|||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
post-expansion = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies.serde_codegen]
|
[dependencies.serde_codegen]
|
||||||
version = "=0.8.16"
|
version = "=0.8.21"
|
||||||
path = "../serde_codegen"
|
path = "../serde_codegen"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["with-syn"]
|
features = ["with-syn"]
|
||||||
@@ -26,5 +23,5 @@ features = ["with-syn"]
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
compiletest_rs = "^0.2.0"
|
compiletest_rs = "^0.2.0"
|
||||||
fnv = "1.0"
|
fnv = "1.0"
|
||||||
serde = { version = "0.8.16", path = "../serde" }
|
serde = { version = "0.8.21", path = "../serde" }
|
||||||
serde_test = { version = "0.8.16", path = "../serde_test" }
|
serde_test = { version = "0.8.21", path = "../serde_test" }
|
||||||
|
|||||||
+4
-12
@@ -1,30 +1,22 @@
|
|||||||
#![feature(proc_macro, proc_macro_lib)]
|
#![feature(proc_macro, proc_macro_lib)]
|
||||||
#![cfg(not(test))]
|
|
||||||
|
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
extern crate serde_codegen;
|
extern crate serde_codegen;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate post_expansion;
|
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
|
|
||||||
#[proc_macro_derive(Serialize)]
|
#[proc_macro_derive(Serialize, attributes(serde))]
|
||||||
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
pub fn derive_serialize(input: TokenStream) -> TokenStream {
|
||||||
let item = format!("#[derive(Serialize)]\n{}", input);
|
match serde_codegen::expand_derive_serialize(&input.to_string()) {
|
||||||
match serde_codegen::expand_single_item(&item) {
|
|
||||||
Ok(expanded) => expanded.parse().unwrap(),
|
Ok(expanded) => expanded.parse().unwrap(),
|
||||||
Err(msg) => panic!(msg),
|
Err(msg) => panic!(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[proc_macro_derive(Deserialize)]
|
#[proc_macro_derive(Deserialize, attributes(serde))]
|
||||||
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
|
||||||
let item = format!("#[derive(Deserialize)]\n{}", input);
|
match serde_codegen::expand_derive_deserialize(&input.to_string()) {
|
||||||
match serde_codegen::expand_single_item(&item) {
|
|
||||||
Ok(expanded) => expanded.parse().unwrap(),
|
Ok(expanded) => expanded.parse().unwrap(),
|
||||||
Err(msg) => panic!(msg),
|
Err(msg) => panic!(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_post_expansion!(PostExpansion_serde);
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_test"
|
name = "serde_test"
|
||||||
version = "0.8.16"
|
version = "0.8.21"
|
||||||
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"
|
||||||
@@ -12,4 +12,4 @@ keywords = ["serde", "serialization"]
|
|||||||
include = ["Cargo.toml", "src/**/*.rs"]
|
include = ["Cargo.toml", "src/**/*.rs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "0.8.16", path = "../serde" }
|
serde = { version = "0.8.21", path = "../serde" }
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "serde_testing"
|
name = "serde_testing"
|
||||||
version = "0.8.16"
|
version = "0.8.21"
|
||||||
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"
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ enum Enum {
|
|||||||
Unit,
|
Unit,
|
||||||
Simple(i32),
|
Simple(i32),
|
||||||
Seq(i32, i32, i32),
|
Seq(i32, i32, i32),
|
||||||
Map { a: i32, b: i32, c: i32 }
|
Map { a: i32, b: i32, c: i32 },
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[serde(skip_deserializing)]
|
||||||
|
Skipped,
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -215,6 +218,9 @@ declare_tests! {
|
|||||||
Token::SeqEnd,
|
Token::SeqEnd,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
test_unit_string {
|
||||||
|
String::new() => &[Token::Unit],
|
||||||
|
}
|
||||||
test_tuple_struct {
|
test_tuple_struct {
|
||||||
TupleStruct(1, 2, 3) => &[
|
TupleStruct(1, 2, 3) => &[
|
||||||
Token::SeqStart(Some(3)),
|
Token::SeqStart(Some(3)),
|
||||||
@@ -802,6 +808,12 @@ declare_error_tests! {
|
|||||||
],
|
],
|
||||||
Error::UnknownVariant("Foo".to_owned()),
|
Error::UnknownVariant("Foo".to_owned()),
|
||||||
}
|
}
|
||||||
|
test_enum_skipped_variant<Enum> {
|
||||||
|
&[
|
||||||
|
Token::EnumUnit("Enum", "Skipped"),
|
||||||
|
],
|
||||||
|
Error::UnknownVariant("Skipped".to_owned()),
|
||||||
|
}
|
||||||
test_struct_seq_too_long<Struct> {
|
test_struct_seq_too_long<Struct> {
|
||||||
&[
|
&[
|
||||||
Token::SeqStart(Some(4)),
|
Token::SeqStart(Some(4)),
|
||||||
|
|||||||
@@ -30,12 +30,20 @@ struct Struct {
|
|||||||
c: i32,
|
c: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize, PartialEq, Debug)]
|
||||||
enum Enum {
|
enum Enum {
|
||||||
Unit,
|
Unit,
|
||||||
One(i32),
|
One(i32),
|
||||||
Seq(i32, i32),
|
Seq(i32, i32),
|
||||||
Map { a: i32, b: i32 },
|
Map { a: i32, b: i32 },
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedUnit,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedOne(i32),
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedSeq(i32, i32),
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
SkippedMap { _a: i32, _b: i32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@@ -388,3 +396,23 @@ fn test_cannot_serialize_paths() {
|
|||||||
&[],
|
&[],
|
||||||
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
|
Error::InvalidValue("Path contains invalid UTF-8 characters".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_enum_skipped() {
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedUnit,
|
||||||
|
&[],
|
||||||
|
Error::InvalidValue("The enum variant Enum::SkippedUnit cannot be serialized".to_owned()));
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedOne(42),
|
||||||
|
&[],
|
||||||
|
Error::InvalidValue("The enum variant Enum::SkippedOne cannot be serialized".to_owned()));
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedSeq(1, 2),
|
||||||
|
&[],
|
||||||
|
Error::InvalidValue("The enum variant Enum::SkippedSeq cannot be serialized".to_owned()));
|
||||||
|
assert_ser_tokens_error(
|
||||||
|
&Enum::SkippedMap { _a: 1, _b: 2 },
|
||||||
|
&[],
|
||||||
|
Error::InvalidValue("The enum variant Enum::SkippedMap cannot be serialized".to_owned()));
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user