Repository: serde-rs/serde
File: serde_codegen/src/attr.rs (Rust)

Code before:
    }
}

/// Represents field attribute information
#[derive(Debug)]
pub struct FieldAttrs {
    name: Name,
    skip_serializing_field: bool,
    skip_deserializing_field: bool,
    skip_serializing_if: Option<ast::Path>,
    default_expr_if_missing: Option<P<ast::Expr>>,
    serialize_with: Option<ast::Path>,
    deserialize_with: Option<ast::Path>,
    ser_bound: Option<Vec<ast::WherePredicate>>,
    de_bound: Option<Vec<ast::WherePredicate>>,
}

impl FieldAttrs {
    /// Extract out the `#[serde(...)]` attributes from a struct field.
    pub fn from_field(cx: &ExtCtxt,
                      index: usize,
                      field: &ast::StructField) -> Result<Self, Error> {
        let builder = AstBuilder::new();

        let field_ident = match field.ident {
            Some(ident) => ident,
            None => builder.id(index.to_string()),
        };

        let mut field_attrs = FieldAttrs {
            name: Name::new(field_ident),
            skip_serializing_field: false,
            skip_deserializing_field: false,
            skip_serializing_if: None,
            default_expr_if_missing: None,
            serialize_with: None,
            deserialize_with: None,
            ser_bound: None,
            de_bound: None,
        };

        for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
            for meta_item in meta_items {
                match meta_item.node {
                    // Parse `#[serde(rename="foo")]`
                    ast::MetaItemKind::NameValue(ref name, ref lit) if name == &"rename" => {
                        let s = try!(get_str_from_lit(cx, name, lit));
                        field_attrs.name.serialize_name = Some(s.clone());
                        field_attrs.name.deserialize_name = Some(s);
                    }


Review comment (suggestion):
It would be also great to support literals and constants as well as functions, so you can actually write

``` rust
#[serde(default="0.1")]
pub field: f32,
```


Code after:
    }
}

/// Represents field attribute information
#[derive(Debug)]
pub struct FieldAttrs {
    name: Name,
    skip_serializing_field: bool,
    skip_deserializing_field: bool,
    skip_serializing_if: Option<ast::Path>,
    default: FieldDefault,
    serialize_with: Option<ast::Path>,
    deserialize_with: Option<ast::Path>,
    ser_bound: Option<Vec<ast::WherePredicate>>,
    de_bound: Option<Vec<ast::WherePredicate>>,
}

/// Represents the default to use for a field when deserializing.
#[derive(Debug, PartialEq)]
pub enum FieldDefault {
    /// Field must always be specified because it does not have a default.
    None,
    /// The default is given by `std::default::Default::default()`.
    Default,
    /// The default is given by this function.
    Path(ast::Path),
}

impl FieldAttrs {
    /// Extract out the `#[serde(...)]` attributes from a struct field.
    pub fn from_field(cx: &ExtCtxt,
                      index: usize,
                      field: &ast::StructField) -> Result<Self, Error> {
        let builder = AstBuilder::new();

        let field_ident = match field.ident {
            Some(ident) => ident,
            None => builder.id(index.to_string()),
        };

        let mut field_attrs = FieldAttrs {
            name: Name::new(field_ident),
            skip_serializing_field: false,
            skip_deserializing_field: false,
            skip_serializing_if: None,
            default: FieldDefault::None,
            serialize_with: None,
            deserialize_with: None,
            ser_bound: None,
            de_bound: None,
        };