Compare commits

...

11 Commits

Author SHA1 Message Date
David Tolnay 9338c4f1b9 Release 0.8.21 2016-12-24 13:10:24 -05:00
David Tolnay 28d67f4172 Format variant-skip message only if variant is skipped 2016-12-24 13:10:06 -05:00
David Tolnay 2401ae61a8 Update to syntex 0.52 2016-12-24 12:42:23 -05:00
David Tolnay 57d3fce0c6 Further simplify variant serialization patterns 2016-12-24 12:28:46 -05:00
David Tolnay a020cceed8 Simplify variant serialize patterns 2016-12-24 12:22:45 -05:00
David Tolnay 49e985eb90 Update message for skipped enum variant 2016-12-24 12:16:28 -05:00
David Tolnay 63def96c66 Merge pull request #653 from shinglyu/skip_se
Implement skip_serializing for enum variant
2016-12-24 11:40:21 -05:00
Shing Lyu 2fea8c9c28 Implement skip_serializing for enum variant 2016-12-24 22:34:22 +08:00
David Tolnay 2c984980a0 Link to release notes from readme 2016-12-22 21:52:37 -05:00
David Tolnay 36f07912b8 Remove no-longer-necessary cfg
This was fixed in Rust, allowing proc macro crates to be tested.
2016-12-17 17:32:11 -08:00
David Tolnay 7222cf7514 Ignore warning from unused enum variant 2016-12-17 17:31:11 -08:00
13 changed files with 132 additions and 89 deletions
+1
View File
@@ -11,6 +11,7 @@ You may be looking for:
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "0.8.20"
version = "0.8.21"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_codegen"
version = "0.8.20"
version = "0.8.21"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -23,7 +23,7 @@ with-syn = []
[dependencies]
clippy = { version = "^0.*", optional = true }
quote = "0.3.8"
serde_codegen_internals = { version = "=0.11.2", default-features = false, path = "../serde_codegen_internals" }
serde_codegen_internals = { version = "=0.11.3", default-features = false, path = "../serde_codegen_internals" }
syn = { version = "0.10", features = ["aster", "visit"] }
syntex = { version = "^0.50.0", optional = true }
syntex_syntax = { version = "^0.50.0", optional = true }
syntex = { version = "^0.52.0", optional = true }
syntex_syntax = { version = "^0.52.0", optional = true }
+6 -7
View File
@@ -38,11 +38,11 @@ fn syntex_registry() -> syntex::Registry {
impl fold::Folder for StripAttributeFolder {
fn fold_attribute(&mut self, attr: ast::Attribute) -> Option<ast::Attribute> {
match attr.node.value.node {
ast::MetaItemKind::List(ref n, _) if n == &"serde" => { return None; }
_ => {}
if attr.value.name == "serde" {
if let ast::MetaItemKind::List(..) = attr.value.node {
return None;
}
}
Some(attr)
}
@@ -118,11 +118,10 @@ macro_rules! shim {
struct MarkSerdeAttributesUsed;
impl visit::Visitor for MarkSerdeAttributesUsed {
fn visit_attribute(&mut self, attr: &ast::Attribute) {
match attr.node.value.node {
ast::MetaItemKind::List(ref name, _) if name == "serde" => {
if attr.value.name == "serde" {
if let ast::MetaItemKind::List(..) = attr.value.node {
attr::mark_used(attr);
}
_ => {}
}
}
}
+71 -67
View File
@@ -256,76 +256,80 @@ fn serialize_variant(
let variant_ident = variant.ident.clone();
let variant_name = variant.attrs.name().serialize_name();
match variant.style {
Style::Unit => {
quote! {
#type_ident::#variant_ident =>
_serde::ser::Serializer::serialize_unit_variant(
_serializer,
#type_name,
#variant_index,
#variant_name,
),
}
},
Style::Newtype => {
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 }
}
if variant.attrs.skip_serializing() {
let skipped_msg = format!("The enum variant {}::{} cannot be serialized",
type_ident, variant_ident);
let skipped_err = quote! {
Err(_serde::ser::Error::invalid_value(#skipped_msg))
};
let fields_pat = match variant.style {
Style::Unit => quote!(),
Style::Newtype | Style::Tuple => quote!( (..) ),
Style::Struct => quote!( {..} ),
};
quote! {
#type_ident::#variant_ident #fields_pat => #skipped_err,
}
Style::Struct => {
let fields = variant.fields.iter().map(|field| {
let id = match field.ident {
Some(ref name) => name.clone(),
None => panic!("struct variant has unnamed fields"),
};
quote!(ref #id)
});
let pat = quote!(#type_ident::#variant_ident { #(#fields),* });
} else { // variant wasn't skipped
match variant.style {
Style::Unit => {
quote! {
#type_ident::#variant_ident =>
_serde::ser::Serializer::serialize_unit_variant(
_serializer,
#type_name,
#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(
variant_index,
variant_name,
generics,
ty,
&variant.fields,
item_attrs,
);
quote! {
#type_ident::#variant_ident(ref __simple_value) => #block,
}
},
Style::Tuple => {
let field_names = (0 .. variant.fields.len())
.map(|i| aster::id(format!("__field{}", i)));
quote! {
#pat => { #block }
let block = serialize_tuple_variant(
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 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_codegen_internals"
version = "0.11.2"
version = "0.11.3"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde codegen. Unstable."
+11
View File
@@ -188,6 +188,7 @@ impl Item {
pub struct Variant {
name: Name,
skip_deserializing: bool,
skip_serializing: bool,
}
impl Variant {
@@ -195,6 +196,7 @@ impl Variant {
let mut ser_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_item in meta_items {
@@ -218,6 +220,10 @@ impl Variant {
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 `{}`",
@@ -237,6 +243,7 @@ impl Variant {
deserialize: de_name.get().unwrap_or_else(|| variant.ident.to_string()),
},
skip_deserializing: skip_deserializing.get(),
skip_serializing: skip_serializing.get(),
}
}
@@ -247,6 +254,10 @@ impl Variant {
pub fn skip_deserializing(&self) -> bool {
self.skip_deserializing
}
pub fn skip_serializing(&self) -> bool {
self.skip_serializing
}
}
/// Represents field attribute information
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "0.8.20"
version = "0.8.21"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -15,7 +15,7 @@ name = "serde_derive"
proc-macro = true
[dependencies.serde_codegen]
version = "=0.8.20"
version = "=0.8.21"
path = "../serde_codegen"
default-features = false
features = ["with-syn"]
@@ -23,5 +23,5 @@ features = ["with-syn"]
[dev-dependencies]
compiletest_rs = "^0.2.0"
fnv = "1.0"
serde = { version = "0.8.20", path = "../serde" }
serde_test = { version = "0.8.20", path = "../serde_test" }
serde = { version = "0.8.21", path = "../serde" }
serde_test = { version = "0.8.21", path = "../serde_test" }
-1
View File
@@ -1,5 +1,4 @@
#![feature(proc_macro, proc_macro_lib)]
#![cfg(not(test))]
extern crate proc_macro;
extern crate serde_codegen;
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "0.8.20"
version = "0.8.21"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
@@ -12,4 +12,4 @@ keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[dependencies]
serde = { version = "0.8.20", path = "../serde" }
serde = { version = "0.8.21", path = "../serde" }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_testing"
version = "0.8.20"
version = "0.8.21"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+1
View File
@@ -38,6 +38,7 @@ enum Enum {
Simple(i32),
Seq(i32, i32, i32),
Map { a: i32, b: i32, c: i32 },
#[allow(dead_code)]
#[serde(skip_deserializing)]
Skipped,
}
+29 -1
View File
@@ -30,12 +30,20 @@ struct Struct {
c: i32,
}
#[derive(Serialize)]
#[derive(Serialize, PartialEq, Debug)]
enum Enum {
Unit,
One(i32),
Seq(i32, 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()));
}
#[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()));
}