Factor default attribute lookup into FieldAttrs

This commit is contained in:
Hugo Duncan 2015-05-01 15:36:50 -04:00
parent cd0ee64892
commit 0f7c67efa7
2 changed files with 31 additions and 43 deletions

View File

@ -395,7 +395,9 @@ fn deserialize_item_enum(
builder,
enum_def.variants.iter()
.map(|variant|
attr::FieldAttrs::new(builder.expr().str(variant.node.name)))
attr::FieldAttrs::new(
true,
builder.expr().str(variant.node.name)))
.collect()
);
@ -743,10 +745,9 @@ fn deserialize_map(
.collect();
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
.zip(struct_def.fields.iter())
.zip(field::struct_field_attrs(cx, builder, struct_def).iter())
.map(|((field_name, field), field_attr)| {
let missing_expr = if field::default_value(field) {
.map(|(field_name, field_attr)| {
let missing_expr = if field_attr.use_default() {
quote_expr!(cx, ::std::default::Default::default())
} else {
let formats = field_attr.formats();

View File

@ -50,10 +50,18 @@ fn rename<'a>(
}
}
fn field_rename_attrs<'a>(
pub fn default_value(mi: &ast::MetaItem) -> bool {
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"default"
} else {
false
}
}
fn field_attrs<'a>(
builder: &aster::AstBuilder,
field: &'a ast::StructField,
) -> Rename<'a> {
) -> (Rename<'a>, bool) {
field.node.attrs.iter()
.find(|sa| {
if let ast::MetaList(ref n, _) = sa.node.value.node {
@ -65,14 +73,15 @@ fn field_rename_attrs<'a>(
.and_then(|sa| {
if let ast::MetaList(_, ref vals) = sa.node.value.node {
attr::mark_used(&sa);
vals.iter().fold(None, |v, mi| {
v.or(rename(builder, mi))
})
Some((vals.iter()
.fold(None, |v, mi| v.or(rename(builder, mi)))
.unwrap_or(Rename::None),
vals.iter().any(|mi| default_value(mi))))
} else {
None
Some((Rename::None, false))
}
})
.unwrap_or(Rename::None)
.unwrap_or((Rename::None, false))
}
pub fn struct_field_attrs(
@ -82,30 +91,33 @@ pub fn struct_field_attrs(
) -> Vec<FieldAttrs> {
struct_def.fields.iter()
.map(|field| {
match field_rename_attrs(builder, field) {
Rename::Global(rename) =>
match field_attrs(builder, field) {
(Rename::Global(rename), default_value) =>
FieldAttrs::new(
default_value,
builder.expr().build_lit(P(rename.clone()))),
Rename::Format(renames) => {
(Rename::Format(renames), default_value) => {
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(
default_field(cx, builder, field.node.kind),
default_value,
default_field_name(cx, builder, field.node.kind),
res)
},
Rename::None => {
(Rename::None, default_value) => {
FieldAttrs::new(
default_field(cx, builder, field.node.kind))
default_value,
default_field_name(cx, builder, field.node.kind))
}
}
})
.collect()
}
fn default_field(
fn default_field_name(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
kind: ast::StructFieldKind,
@ -119,28 +131,3 @@ fn default_field(
}
}
}
pub fn default_value(field: &ast::StructField) -> bool {
field.node.attrs.iter()
.any(|sa| {
if let ast::MetaItem_::MetaList(ref n, ref vals) = sa.node.value.node {
if n == &"serde" {
attr::mark_used(&sa);
vals.iter()
.map(|mi|
if let ast::MetaItem_::MetaWord(ref n) = mi.node {
n == &"default"
} else {
false
})
.any(|x| x)
} else {
false
}
}
else {
false
}
})
}