Add support for #[serde(default)] on structs

This allows structs to use the default value for each field defined in
the struct’s `std::default::Default` implementation, rather then the
default value for the field’s type.

```
struct StructDefault {
    a: i32,
    b: String,
}

impl Default for StructDefault {
    fn default() -> StructDefault {
        StructDefault{
            a: 100,
            b: "default".to_string(),
        }
    }
}
```

The code above will now return `100` for field `a` and `”default”` for
`b`, rather then `0` and `””` respectively.
This commit is contained in:
Thomas de Zeeuw
2017-02-20 22:34:52 +01:00
parent 535ab1e04b
commit 9444db5f19
3 changed files with 74 additions and 4 deletions
+12
View File
@@ -90,6 +90,7 @@ impl Name {
pub struct Item {
name: Name,
deny_unknown_fields: bool,
default: bool,
ser_bound: Option<Vec<syn::WherePredicate>>,
de_bound: Option<Vec<syn::WherePredicate>>,
tag: EnumTag,
@@ -133,6 +134,7 @@ impl Item {
let mut ser_name = Attr::none(cx, "rename");
let mut de_name = Attr::none(cx, "rename");
let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
let mut default = BoolAttr::none(cx, "default");
let mut ser_bound = Attr::none(cx, "bound");
let mut de_bound = Attr::none(cx, "bound");
let mut untagged = BoolAttr::none(cx, "untagged");
@@ -163,6 +165,11 @@ impl Item {
deny_unknown_fields.set_true();
}
// Parse `#[serde(default)]`
MetaItem(Word(ref name)) if name == "default" => {
default.set_true();
}
// Parse `#[serde(bound="D: Serialize")]`
MetaItem(NameValue(ref name, ref lit)) if name == "bound" => {
if let Ok(where_predicates) =
@@ -281,6 +288,7 @@ impl Item {
deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
},
deny_unknown_fields: deny_unknown_fields.get(),
default: default.get(),
ser_bound: ser_bound.get(),
de_bound: de_bound.get(),
tag: tag,
@@ -295,6 +303,10 @@ impl Item {
self.deny_unknown_fields
}
pub fn default(&self) -> bool {
self.default
}
pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
self.ser_bound.as_ref().map(|vec| &vec[..])
}