Add serialize, deserialize specific rename

Adds the rename_serialize and rename_deserialize field attributes to
specify serialisation and deserialisation specific renames.
This commit is contained in:
Hugo Duncan 2015-04-21 10:57:36 -04:00
parent 195f7380b5
commit fd6462f8d1
4 changed files with 36 additions and 6 deletions

View File

@ -596,7 +596,7 @@ fn deserialize_struct_visitor(
let field_visitor = deserialize_field_visitor(
cx,
builder,
field::struct_field_strs(cx, builder, struct_def),
field::struct_field_strs(cx, builder, struct_def, field::Direction::Deserialize),
);
let visit_map_expr = deserialize_map(

View File

@ -5,7 +5,19 @@ use syntax::ptr::P;
use aster;
fn field_rename(field: &ast::StructField) -> Option<&ast::Lit> {
pub enum Direction {
Serialize,
Deserialize,
}
fn field_rename<'a>(
field: &'a ast::StructField,
direction: &Direction,
) -> Option<&'a ast::Lit> {
let dir_attr = match *direction {
Direction::Serialize => "rename_serialize",
Direction::Deserialize => "rename_deserialize",
};
field.node.attrs.iter()
.find(|sa| {
if let ast::MetaList(ref n, _) = sa.node.value.node {
@ -19,7 +31,7 @@ fn field_rename(field: &ast::StructField) -> Option<&ast::Lit> {
attr::mark_used(&sa);
vals.iter().fold(None, |v, mi| {
if let ast::MetaNameValue(ref n, ref lit) = mi.node {
if n == &"rename" {
if n == &"rename" || n == &dir_attr {
Some(lit)
} else {
v
@ -38,10 +50,11 @@ pub fn struct_field_strs(
cx: &ExtCtxt,
builder: &aster::AstBuilder,
struct_def: &ast::StructDef,
direction: Direction,
) -> Vec<P<ast::Expr>> {
struct_def.fields.iter()
.map(|field| {
match field_rename(field) {
match field_rename(field, &direction) {
Some(rename) => builder.expr().build_lit(P(rename.clone())),
None => {
match field.node.kind {

View File

@ -13,7 +13,7 @@ use syntax::ptr::P;
use aster;
use field::struct_field_strs;
use field::{Direction, struct_field_strs};
pub fn expand_derive_serialize(
cx: &mut ExtCtxt,
@ -517,7 +517,7 @@ fn serialize_struct_visitor<I>(
{
let len = struct_def.fields.len();
let key_exprs = struct_field_strs(cx, builder, struct_def);
let key_exprs = struct_field_strs(cx, builder, struct_def, Direction::Serialize);
let arms: Vec<ast::Arm> = key_exprs.iter()
.zip(value_exprs)

View File

@ -20,6 +20,13 @@ struct Rename {
a2: i32,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct DirectionRename {
a1: i32,
#[serde(rename_serialize="a3", rename_deserialize="a4")]
a2: i32,
}
#[test]
fn test_default() {
let deserialized_value: Default = json::from_str(&"{\"a1\":1,\"a2\":2}").unwrap();
@ -38,3 +45,13 @@ fn test_rename() {
let deserialized_value: Rename = json::from_str(&serialized_value).unwrap();
assert_eq!(value, deserialized_value);
}
#[test]
fn test_direction_rename() {
let value = DirectionRename { a1: 1, a2: 2 };
let serialized_value = json::to_string(&value).unwrap();
assert_eq!(serialized_value, "{\"a1\":1,\"a3\":2}");
let deserialized_value = json::from_str("{\"a1\":1,\"a4\":2}").unwrap();
assert_eq!(value, deserialized_value);
}