mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-13 16:01:02 +00:00
Cleanup, and move default::Default #[derive_deserialize] support to get called when missing
This commit is contained in:
+47
-70
@@ -10,7 +10,6 @@ use syntax::ast;
|
|||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::ExtCtxt;
|
use syntax::ext::base::ExtCtxt;
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::parse::token;
|
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
use aster;
|
use aster;
|
||||||
@@ -142,7 +141,6 @@ fn deserialize_item_struct(
|
|||||||
impl_generics,
|
impl_generics,
|
||||||
ty,
|
ty,
|
||||||
struct_def,
|
struct_def,
|
||||||
named_fields,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
(false, false) => {
|
(false, false) => {
|
||||||
@@ -242,10 +240,6 @@ fn deserialize_tuple_struct(
|
|||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let where_clause = &impl_generics.where_clause;
|
let where_clause = &impl_generics.where_clause;
|
||||||
|
|
||||||
let field_names: Vec<ast::Ident> = (0 .. fields)
|
|
||||||
.map(|i| builder.id(&format!("__field{}", i)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
|
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
|
||||||
builder,
|
builder,
|
||||||
impl_generics,
|
impl_generics,
|
||||||
@@ -255,7 +249,7 @@ fn deserialize_tuple_struct(
|
|||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
builder.path().id(type_ident).build(),
|
builder.path().id(type_ident).build(),
|
||||||
&field_names,
|
fields,
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_name = builder.expr().str(type_ident);
|
let type_name = builder.expr().str(type_ident);
|
||||||
@@ -293,10 +287,11 @@ fn deserialize_seq(
|
|||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
struct_path: ast::Path,
|
struct_path: ast::Path,
|
||||||
field_names: &[Ident],
|
fields: usize,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let let_values: Vec<P<ast::Stmt>> = field_names.iter()
|
let let_values: Vec<P<_>> = (0 .. fields)
|
||||||
.map(|name| {
|
.map(|i| {
|
||||||
|
let name = builder.id(format!("__field{}", i));
|
||||||
quote_stmt!(cx,
|
quote_stmt!(cx,
|
||||||
let $name = match try!(visitor.visit()) {
|
let $name = match try!(visitor.visit()) {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
@@ -310,7 +305,7 @@ fn deserialize_seq(
|
|||||||
|
|
||||||
let result = builder.expr().call()
|
let result = builder.expr().call()
|
||||||
.build_path(struct_path)
|
.build_path(struct_path)
|
||||||
.with_args(field_names.iter().map(|name| builder.expr().id(*name)))
|
.with_args((0 .. fields).map(|i| builder.expr().id(format!("__field{}", i))))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
quote_expr!(cx, {
|
quote_expr!(cx, {
|
||||||
@@ -329,7 +324,6 @@ fn deserialize_struct(
|
|||||||
impl_generics: &ast::Generics,
|
impl_generics: &ast::Generics,
|
||||||
ty: P<ast::Ty>,
|
ty: P<ast::Ty>,
|
||||||
struct_def: &StructDef,
|
struct_def: &StructDef,
|
||||||
fields: Vec<Ident>,
|
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let where_clause = &impl_generics.where_clause;
|
let where_clause = &impl_generics.where_clause;
|
||||||
|
|
||||||
@@ -343,7 +337,6 @@ fn deserialize_struct(
|
|||||||
builder,
|
builder,
|
||||||
struct_def,
|
struct_def,
|
||||||
builder.path().id(type_ident).build(),
|
builder.path().id(type_ident).build(),
|
||||||
fields,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_name = builder.expr().str(type_ident);
|
let type_name = builder.expr().str(type_ident);
|
||||||
@@ -385,41 +378,47 @@ fn deserialize_map(
|
|||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
struct_path: ast::Path,
|
struct_path: ast::Path,
|
||||||
field_names: &[Ident],
|
|
||||||
fields: Vec<Ident>,
|
|
||||||
struct_def: &StructDef,
|
struct_def: &StructDef,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
|
// Create the field names for the fields.
|
||||||
|
let field_names: Vec<ast::Ident> = (0 .. struct_def.fields.len())
|
||||||
|
.map(|i| builder.id(format!("__field{}", i)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
// Declare each field.
|
// Declare each field.
|
||||||
let let_values: Vec<P<ast::Stmt>> = field_names.iter()
|
let let_values: Vec<P<ast::Stmt>> = field_names.iter()
|
||||||
.zip(struct_def.fields.iter())
|
.map(|field_name| quote_stmt!(cx, let mut $field_name = None;))
|
||||||
.map(|(field, sf)| {
|
|
||||||
if field::default_value(sf) {
|
|
||||||
quote_stmt!(cx,
|
|
||||||
let mut $field = Some(::std::default::Default::default());
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
quote_stmt!(cx, let mut $field = None;)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Match arms to extract a value for a field.
|
// Match arms to extract a value for a field.
|
||||||
let value_arms: Vec<ast::Arm> = field_names.iter()
|
let value_arms: Vec<ast::Arm> = field_names.iter()
|
||||||
.map(|field| {
|
.map(|field_name| {
|
||||||
quote_arm!(cx, __Field::$field => {
|
quote_arm!(cx,
|
||||||
$field = Some(try!(visitor.visit_value()));
|
__Field::$field_name => {
|
||||||
})
|
$field_name = Some(try!(visitor.visit_value()));
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let extract_values: Vec<P<ast::Stmt>> = fields.iter()
|
let extract_values: Vec<P<ast::Stmt>> = field_names.iter()
|
||||||
.zip(field_names.iter())
|
.zip(struct_def.fields.iter())
|
||||||
.map(|(name, field)| {
|
.map(|(field_name, field)| {
|
||||||
let name_str = builder.expr().str(name);
|
let name_str = match field.node.kind {
|
||||||
|
ast::NamedField(name, _) => builder.expr().str(name),
|
||||||
|
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let missing_expr = if field::default_value(field) {
|
||||||
|
quote_expr!(cx, ::std::default::Default::default())
|
||||||
|
} else {
|
||||||
|
quote_expr!(cx, try!(visitor.missing_field($name_str)))
|
||||||
|
};
|
||||||
|
|
||||||
quote_stmt!(cx,
|
quote_stmt!(cx,
|
||||||
let $field = match $field {
|
let $field_name = match $field_name {
|
||||||
Some($field) => $field,
|
Some($field_name) => $field_name,
|
||||||
None => try!(visitor.missing_field($name_str)),
|
None => $missing_expr,
|
||||||
};
|
};
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -429,13 +428,13 @@ fn deserialize_map(
|
|||||||
.with_id_exprs(
|
.with_id_exprs(
|
||||||
struct_def.fields.iter()
|
struct_def.fields.iter()
|
||||||
.zip(field_names.iter())
|
.zip(field_names.iter())
|
||||||
.map(|(field, local)| {
|
.map(|(field, field_name)| {
|
||||||
(
|
(
|
||||||
match field.node.kind {
|
match field.node.kind {
|
||||||
ast::NamedField(name, _) => name.clone(),
|
ast::NamedField(name, _) => name.clone(),
|
||||||
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
|
ast::UnnamedField(_) => panic!("struct contains unnamed fields"),
|
||||||
},
|
},
|
||||||
builder.expr().id(local),
|
builder.expr().id(field_name),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -542,10 +541,6 @@ fn deserialize_variant(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::TupleVariantKind(ref args) => {
|
ast::TupleVariantKind(ref args) => {
|
||||||
let fields: Vec<ast::Ident> = (0 .. args.len())
|
|
||||||
.map(|i| builder.id(format!("__field{}", i)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let expr = deserialize_tuple_variant(
|
let expr = deserialize_tuple_variant(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -553,16 +548,12 @@ fn deserialize_variant(
|
|||||||
variant_ident,
|
variant_ident,
|
||||||
generics,
|
generics,
|
||||||
ty,
|
ty,
|
||||||
fields,
|
args.len(),
|
||||||
);
|
);
|
||||||
|
|
||||||
quote_arm!(cx, $variant_name => { $expr })
|
quote_arm!(cx, $variant_name => { $expr })
|
||||||
}
|
}
|
||||||
ast::StructVariantKind(ref struct_def) => {
|
ast::StructVariantKind(ref struct_def) => {
|
||||||
let fields: Vec<_> = (0 .. struct_def.fields.len())
|
|
||||||
.map(|i| builder.id(format!("__field{}", i)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let expr = deserialize_struct_variant(
|
let expr = deserialize_struct_variant(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
@@ -571,7 +562,6 @@ fn deserialize_variant(
|
|||||||
generics,
|
generics,
|
||||||
ty,
|
ty,
|
||||||
struct_def,
|
struct_def,
|
||||||
fields,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
quote_arm!(cx, $variant_name => { $expr })
|
quote_arm!(cx, $variant_name => { $expr })
|
||||||
@@ -586,15 +576,10 @@ fn deserialize_tuple_variant(
|
|||||||
variant_ident: ast::Ident,
|
variant_ident: ast::Ident,
|
||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
ty: P<ast::Ty>,
|
ty: P<ast::Ty>,
|
||||||
fields: Vec<Ident>,
|
fields: usize,
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let where_clause = &generics.where_clause;
|
let where_clause = &generics.where_clause;
|
||||||
|
|
||||||
// Create the field names for the fields.
|
|
||||||
let field_names: Vec<ast::Ident> = (0 .. fields.len())
|
|
||||||
.map(|i| token::str_to_ident(&format!("__field{}", i)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
|
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
|
||||||
builder,
|
builder,
|
||||||
generics,
|
generics,
|
||||||
@@ -604,7 +589,7 @@ fn deserialize_tuple_variant(
|
|||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
builder.path().id(type_ident).id(variant_ident).build(),
|
builder.path().id(type_ident).id(variant_ident).build(),
|
||||||
&field_names,
|
fields,
|
||||||
);
|
);
|
||||||
|
|
||||||
quote_expr!(cx, {
|
quote_expr!(cx, {
|
||||||
@@ -632,7 +617,6 @@ fn deserialize_struct_variant(
|
|||||||
generics: &ast::Generics,
|
generics: &ast::Generics,
|
||||||
ty: P<ast::Ty>,
|
ty: P<ast::Ty>,
|
||||||
struct_def: &ast::StructDef,
|
struct_def: &ast::StructDef,
|
||||||
fields: Vec<Ident>,
|
|
||||||
) -> P<ast::Expr> {
|
) -> P<ast::Expr> {
|
||||||
let where_clause = &generics.where_clause;
|
let where_clause = &generics.where_clause;
|
||||||
|
|
||||||
@@ -641,7 +625,6 @@ fn deserialize_struct_variant(
|
|||||||
builder,
|
builder,
|
||||||
struct_def,
|
struct_def,
|
||||||
builder.path().id(type_ident).id(variant_ident).build(),
|
builder.path().id(type_ident).id(variant_ident).build(),
|
||||||
fields,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
|
let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
|
||||||
@@ -671,9 +654,13 @@ fn deserialize_struct_variant(
|
|||||||
fn deserialize_field_visitor(
|
fn deserialize_field_visitor(
|
||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
field_names: &[ast::Ident],
|
|
||||||
struct_def: &StructDef,
|
struct_def: &StructDef,
|
||||||
) -> Vec<P<ast::Item>> {
|
) -> Vec<P<ast::Item>> {
|
||||||
|
// Create the field names for the fields.
|
||||||
|
let field_names: Vec<ast::Ident> = (0 .. struct_def.fields.len())
|
||||||
|
.map(|i| builder.id(format!("__field{}", i)))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let field_enum = builder.item()
|
let field_enum = builder.item()
|
||||||
.attr().allow(&["non_camel_case_types"])
|
.attr().allow(&["non_camel_case_types"])
|
||||||
.enum_("__Field")
|
.enum_("__Field")
|
||||||
@@ -690,8 +677,8 @@ fn deserialize_field_visitor(
|
|||||||
// Match arms to extract a field from a string
|
// Match arms to extract a field from a string
|
||||||
let field_arms: Vec<ast::Arm> = aliases.iter()
|
let field_arms: Vec<ast::Arm> = aliases.iter()
|
||||||
.zip(field_names.iter())
|
.zip(field_names.iter())
|
||||||
.map(|(alias, field)| {
|
.map(|(alias, field_name)| {
|
||||||
quote_arm!(cx, $alias => { Ok(__Field::$field) })
|
quote_arm!(cx, $alias => { Ok(__Field::$field_name) })
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@@ -731,18 +718,10 @@ fn deserialize_struct_visitor(
|
|||||||
builder: &aster::AstBuilder,
|
builder: &aster::AstBuilder,
|
||||||
struct_def: &ast::StructDef,
|
struct_def: &ast::StructDef,
|
||||||
struct_path: ast::Path,
|
struct_path: ast::Path,
|
||||||
fields: Vec<Ident>,
|
|
||||||
) -> (Vec<P<ast::Item>>, P<ast::Expr>) {
|
) -> (Vec<P<ast::Item>>, P<ast::Expr>) {
|
||||||
|
|
||||||
// Create the field names for the fields.
|
|
||||||
let field_names: Vec<ast::Ident> = (0 .. struct_def.fields.len())
|
|
||||||
.map(|i| builder.id(format!("__field{}", i)))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let field_visitor = deserialize_field_visitor(
|
let field_visitor = deserialize_field_visitor(
|
||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
&field_names,
|
|
||||||
struct_def,
|
struct_def,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -750,8 +729,6 @@ fn deserialize_struct_visitor(
|
|||||||
cx,
|
cx,
|
||||||
builder,
|
builder,
|
||||||
struct_path,
|
struct_path,
|
||||||
&field_names,
|
|
||||||
fields,
|
|
||||||
struct_def,
|
struct_def,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user