allow the deserializer to optionally handle missing fields

This allows json to deserialize missing values as a `null`.
This commit is contained in:
Erick Tryzelaar
2014-08-18 07:37:44 -07:00
parent c6d28afb6f
commit aff53e8dd4
7 changed files with 80 additions and 70 deletions
+10 -38
View File
@@ -394,23 +394,18 @@ fn deserialize_struct_from_map(
})
.collect();
let fields_tuple = cx.expr_tuple(
span,
fields.iter()
.map(|&(name, span)| {
cx.expr_ident(span, name)
})
.collect()
);
let fields_pats: Vec<Gc<ast::Pat>> = fields.iter()
let extract_fields: Vec<Gc<ast::Stmt>> = fields.iter()
.map(|&(name, span)| {
quote_pat!(cx, Some($name))
let name_str = cx.expr_str(span, token::get_ident(name));
quote_stmt!(cx,
let $name = match $name {
Some($name) => $name,
None => try!($deserializer.missing_field($name_str)),
};
)
})
.collect();
let fields_pat = cx.pat_tuple(span, fields_pats);
let result = cx.expr_struct_ident(
span,
type_ident,
@@ -421,27 +416,6 @@ fn deserialize_struct_from_map(
.collect()
);
let error_arms: Vec<ast::Arm> = fields.iter()
.map(|&(name, span)| {
let pats = fields.iter()
.map(|&(n, _)| {
if n == name {
quote_pat!(cx, None)
} else {
quote_pat!(cx, _)
}
})
.collect();
let pat = cx.pat_tuple(span, pats);
let s = cx.expr_str(span, token::get_ident(name));
quote_arm!(cx,
$pat => Err($deserializer.missing_field_error($s)),
)
})
.collect();
quote_expr!(cx, {
$let_fields
@@ -473,10 +447,8 @@ fn deserialize_struct_from_map(
try!($deserializer.ignore_field(token))
}
match $fields_tuple {
$fields_pat => Ok($result),
$error_arms
}
$extract_fields
Ok($result)
})
}