Add `#[serde(skip_serializing)] to skip serializing some fields

Closes #99
This commit is contained in:
Erick Tryzelaar
2015-07-23 08:07:49 -07:00
parent 447d08bd91
commit b1cb5379de
5 changed files with 58 additions and 12 deletions
+15 -2
View File
@@ -16,14 +16,20 @@ pub enum FieldNames {
/// Represents field attribute information
pub struct FieldAttrs {
skip_serializing_field: bool,
names: FieldNames,
use_default: bool,
}
impl FieldAttrs {
/// Create a FieldAttr with a single default field name
pub fn new(default_value: bool, name: P<ast::Expr>) -> FieldAttrs {
pub fn new(
skip_serializing_field: bool,
default_value: bool,
name: P<ast::Expr>,
) -> FieldAttrs {
FieldAttrs {
skip_serializing_field: skip_serializing_field,
names: FieldNames::Global(name),
use_default: default_value,
}
@@ -31,12 +37,14 @@ impl FieldAttrs {
/// Create a FieldAttr with format specific field names
pub fn new_with_formats(
skip_serializing_field: bool,
default_value: bool,
default_name: P<ast::Expr>,
formats: HashMap<P<ast::Expr>, P<ast::Expr>>,
) -> FieldAttrs {
FieldAttrs {
names: FieldNames::Format {
skip_serializing_field: skip_serializing_field,
names: FieldNames::Format {
formats: formats,
default: default_name,
},
@@ -104,4 +112,9 @@ impl FieldAttrs {
pub fn use_default(&self) -> bool {
self.use_default
}
/// Predicate for ignoring a field when serializing a value
pub fn skip_serializing_field(&self) -> bool {
self.skip_serializing_field
}
}
+1
View File
@@ -483,6 +483,7 @@ fn deserialize_item_enum(
enum_def.variants.iter()
.map(|variant|
attr::FieldAttrs::new(
false,
true,
builder.expr().str(variant.node.name)))
.collect()
+24 -10
View File
@@ -58,10 +58,18 @@ fn default_value(mi: &ast::MetaItem) -> bool {
}
}
fn skip_serializing_field(mi: &ast::MetaItem) -> bool {
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"skip_serializing"
} else {
false
}
}
fn field_attrs<'a>(
builder: &aster::AstBuilder,
field: &'a ast::StructField,
) -> (Rename<'a>, bool) {
) -> (Rename<'a>, bool, bool) {
field.node.attrs.iter()
.find(|sa| {
if let ast::MetaList(ref n, _) = sa.node.value.node {
@@ -73,15 +81,18 @@ fn field_attrs<'a>(
.and_then(|sa| {
if let ast::MetaList(_, ref vals) = sa.node.value.node {
attr::mark_used(&sa);
Some((vals.iter()
.fold(None, |v, mi| v.or(rename(builder, mi)))
.unwrap_or(Rename::None),
vals.iter().any(|mi| default_value(mi))))
Some((
vals.iter()
.fold(None, |v, mi| v.or(rename(builder, mi)))
.unwrap_or(Rename::None),
vals.iter().any(|mi| default_value(mi)),
vals.iter().any(|mi| skip_serializing_field(mi)),
))
} else {
Some((Rename::None, false))
Some((Rename::None, false, false))
}
})
.unwrap_or((Rename::None, false))
.unwrap_or((Rename::None, false, false))
}
pub fn struct_field_attrs(
@@ -92,23 +103,26 @@ pub fn struct_field_attrs(
struct_def.fields.iter()
.map(|field| {
match field_attrs(builder, field) {
(Rename::Global(rename), default_value) =>
(Rename::Global(rename), default_value, skip_serializing_field) =>
FieldAttrs::new(
skip_serializing_field,
default_value,
builder.expr().build_lit(P(rename.clone()))),
(Rename::Format(renames), default_value) => {
(Rename::Format(renames), default_value, skip_serializing_field) => {
let mut res = HashMap::new();
res.extend(
renames.into_iter()
.map(|(k,v)|
(k, builder.expr().build_lit(P(v.clone())))));
FieldAttrs::new_with_formats(
skip_serializing_field,
default_value,
default_field_name(cx, builder, field.node.kind),
res)
},
(Rename::None, default_value) => {
(Rename::None, default_value, skip_serializing_field) => {
FieldAttrs::new(
skip_serializing_field,
default_value,
default_field_name(cx, builder, field.node.kind))
}
+1
View File
@@ -550,6 +550,7 @@ fn serialize_struct_visitor<I>(
let arms: Vec<ast::Arm> = field_attrs.into_iter()
.zip(value_exprs)
.filter(|&(ref field, _)| !field.skip_serializing_field())
.enumerate()
.map(|(i, (field, value_expr))| {
let key_expr = field.serializer_key_expr(cx);