Add constructor functions for FieldAttrs

This commit is contained in:
Hugo Duncan
2015-05-01 15:01:01 -04:00
parent ec3af2cb6a
commit cd0ee64892
3 changed files with 51 additions and 44 deletions
+3 -3
View File
@@ -395,7 +395,7 @@ fn deserialize_item_enum(
builder, builder,
enum_def.variants.iter() enum_def.variants.iter()
.map(|variant| .map(|variant|
attr::FieldAttrs::Global(builder.expr().str(variant.node.name))) attr::FieldAttrs::new(builder.expr().str(variant.node.name)))
.collect() .collect()
); );
@@ -702,7 +702,7 @@ fn deserialize_struct_visitor(
let field_visitor = deserialize_field_visitor( let field_visitor = deserialize_field_visitor(
cx, cx,
builder, builder,
field::struct_field_strs(cx, builder, struct_def), field::struct_field_attrs(cx, builder, struct_def),
); );
let visit_map_expr = deserialize_map( let visit_map_expr = deserialize_map(
@@ -744,7 +744,7 @@ fn deserialize_map(
let extract_values: Vec<P<ast::Stmt>> = field_names.iter() let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
.zip(struct_def.fields.iter()) .zip(struct_def.fields.iter())
.zip(field::struct_field_strs(cx, builder, struct_def).iter()) .zip(field::struct_field_attrs(cx, builder, struct_def).iter())
.map(|((field_name, field), field_attr)| { .map(|((field_name, field), field_attr)| {
let missing_expr = if field::default_value(field) { let missing_expr = if field::default_value(field) {
quote_expr!(cx, ::std::default::Default::default()) quote_expr!(cx, ::std::default::Default::default())
+45 -38
View File
@@ -9,13 +9,48 @@ use aster;
use attr::FieldAttrs; use attr::FieldAttrs;
pub enum Rename<'a> { enum Rename<'a> {
None, None,
Global(&'a ast::Lit), Global(&'a ast::Lit),
Format(HashMap<P<ast::Expr>, &'a ast::Lit>) Format(HashMap<P<ast::Expr>, &'a ast::Lit>)
} }
pub fn field_rename<'a>( fn rename<'a>(
builder: &aster::AstBuilder,
mi: &'a ast::MetaItem,
) -> Option<Rename<'a>>
{
match mi.node {
ast::MetaNameValue(ref n, ref lit) => {
if n == &"rename" {
Some(Rename::Global(lit))
} else {
None
}
},
ast::MetaList(ref n, ref items) => {
if n == &"rename" {
let mut m = HashMap::new();
m.extend(
items.iter()
.filter_map(
|item|
match item.node {
ast::MetaNameValue(ref n, ref lit) =>
Some((builder.expr().str(n),
lit)),
_ => None
}));
Some(Rename::Format(m))
} else {
None
}
},
_ => None
}
}
fn field_rename_attrs<'a>(
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
field: &'a ast::StructField, field: &'a ast::StructField,
) -> Rename<'a> { ) -> Rename<'a> {
@@ -31,34 +66,7 @@ pub fn field_rename<'a>(
if let ast::MetaList(_, ref vals) = sa.node.value.node { if let ast::MetaList(_, ref vals) = sa.node.value.node {
attr::mark_used(&sa); attr::mark_used(&sa);
vals.iter().fold(None, |v, mi| { vals.iter().fold(None, |v, mi| {
match mi.node { v.or(rename(builder, mi))
ast::MetaNameValue(ref n, ref lit) => {
if n == &"rename" {
Some(Rename::Global(lit))
} else {
v
}
},
ast::MetaList(ref n, ref items) => {
if n == &"rename" {
let mut m = HashMap::new();
m.extend(
items.iter()
.filter_map(
|item|
match item.node {
ast::MetaNameValue(ref n, ref lit) =>
Some((builder.expr().str(n),
lit)),
_ => None
}));
Some(Rename::Format(m))
} else {
v
}
},
_ => {v}
}
}) })
} else { } else {
None None
@@ -67,16 +75,16 @@ pub fn field_rename<'a>(
.unwrap_or(Rename::None) .unwrap_or(Rename::None)
} }
pub fn struct_field_strs( pub fn struct_field_attrs(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
struct_def: &ast::StructDef, struct_def: &ast::StructDef,
) -> Vec<FieldAttrs> { ) -> Vec<FieldAttrs> {
struct_def.fields.iter() struct_def.fields.iter()
.map(|field| { .map(|field| {
match field_rename(builder, field) { match field_rename_attrs(builder, field) {
Rename::Global(rename) => Rename::Global(rename) =>
FieldAttrs::Global( FieldAttrs::new(
builder.expr().build_lit(P(rename.clone()))), builder.expr().build_lit(P(rename.clone()))),
Rename::Format(renames) => { Rename::Format(renames) => {
let mut res = HashMap::new(); let mut res = HashMap::new();
@@ -84,13 +92,12 @@ pub fn struct_field_strs(
renames.into_iter() renames.into_iter()
.map(|(k,v)| .map(|(k,v)|
(k, builder.expr().build_lit(P(v.clone()))))); (k, builder.expr().build_lit(P(v.clone())))));
FieldAttrs::Format{ FieldAttrs::new_with_formats(
formats: res, default_field(cx, builder, field.node.kind),
default: default_field(cx, builder, field.node.kind), res)
}
}, },
Rename::None => { Rename::None => {
FieldAttrs::Global( FieldAttrs::new(
default_field(cx, builder, field.node.kind)) default_field(cx, builder, field.node.kind))
} }
} }
+3 -3
View File
@@ -13,7 +13,7 @@ use syntax::ptr::P;
use aster; use aster;
use field::struct_field_strs; use field::struct_field_attrs;
pub fn expand_derive_serialize( pub fn expand_derive_serialize(
cx: &mut ExtCtxt, cx: &mut ExtCtxt,
@@ -517,9 +517,9 @@ fn serialize_struct_visitor<I>(
{ {
let len = struct_def.fields.len(); let len = struct_def.fields.len();
let key_exprs = struct_field_strs(cx, builder, struct_def); let field_attrs = struct_field_attrs(cx, builder, struct_def);
let arms: Vec<ast::Arm> = key_exprs.into_iter() let arms: Vec<ast::Arm> = field_attrs.into_iter()
.zip(value_exprs) .zip(value_exprs)
.enumerate() .enumerate()
.map(|(i, (field, value_expr))| { .map(|(i, (field, value_expr))| {