diff --git a/serde_macros/src/de.rs b/serde_macros/src/de.rs index a47ad0ab..14716bf0 100644 --- a/serde_macros/src/de.rs +++ b/serde_macros/src/de.rs @@ -639,9 +639,11 @@ fn deserialize_map( let extract_values: Vec> = field_names.iter() .zip(struct_def.fields.iter()) .map(|(field_name, field)| { - let name_str = match field.node.kind { - ast::NamedField(name, _) => builder.expr().str(name), - ast::UnnamedField(_) => panic!("struct contains unnamed fields"), + let rename = field::field_rename(field, &field::Direction::Deserialize); + let name_str = match (rename, field.node.kind) { + (Some(rename), _) => builder.expr().build_lit(P(rename.clone())), + (None, ast::NamedField(name, _)) => builder.expr().str(name), + (None, ast::UnnamedField(_)) => panic!("struct contains unnamed fields"), }; let missing_expr = if field::default_value(field) { diff --git a/serde_macros/src/field.rs b/serde_macros/src/field.rs index baa79009..c35e694b 100644 --- a/serde_macros/src/field.rs +++ b/serde_macros/src/field.rs @@ -10,7 +10,7 @@ pub enum Direction { Deserialize, } -fn field_rename<'a>( +pub fn field_rename<'a>( field: &'a ast::StructField, direction: &Direction, ) -> Option<&'a ast::Lit> { diff --git a/tests/test_json.rs b/tests/test_json.rs index 2135f0c5..ba45d974 100644 --- a/tests/test_json.rs +++ b/tests/test_json.rs @@ -1,4 +1,4 @@ -#![feature(custom_derive, plugin, test)] +#![feature(custom_derive, plugin, test, custom_attribute)] #![plugin(serde_macros)] extern crate test; @@ -1019,3 +1019,26 @@ fn test_missing_field() { ))).unwrap(); assert_eq!(value, Foo { x: Some(5) }); } + +#[test] +fn test_missing_renamed_field() { + #[derive(Debug, PartialEq, Deserialize)] + struct Foo { + #[serde(rename_deserialize="y")] + x: Option, + } + + let value: Foo = from_str("{}").unwrap(); + assert_eq!(value, Foo { x: None }); + + let value: Foo = from_str("{\"y\": 5}").unwrap(); + assert_eq!(value, Foo { x: Some(5) }); + + let value: Foo = from_value(Value::Object(treemap!())).unwrap(); + assert_eq!(value, Foo { x: None }); + + let value: Foo = from_value(Value::Object(treemap!( + "y".to_string() => Value::I64(5) + ))).unwrap(); + assert_eq!(value, Foo { x: Some(5) }); +}