Fixed the struct map interaction with serial_name. Added a separarte JSON test for serial_name.

This commit is contained in:
kvark 2014-09-07 10:43:15 -04:00
parent 4a713cdbea
commit 2224e9afdf
3 changed files with 55 additions and 12 deletions

View File

@ -844,7 +844,6 @@ fn bench_manual_mem_writer_no_escape(b: &mut Bencher) {
b.iter(|| { b.iter(|| {
let mut wr = MemWriter::with_capacity(1024); let mut wr = MemWriter::with_capacity(1024);
manual_no_escape(wr.by_ref(), &log); manual_no_escape(wr.by_ref(), &log);
let _json = wr.unwrap(); let _json = wr.unwrap();
//let _json = String::from_utf8(_json).unwrap(); //let _json = String::from_utf8(_json).unwrap();

View File

@ -291,15 +291,16 @@ fn deserialize_struct(
deserializer: Gc<ast::Expr>, deserializer: Gc<ast::Expr>,
token: Gc<ast::Expr> token: Gc<ast::Expr>
) -> Gc<ast::Expr> { ) -> Gc<ast::Expr> {
let serial_names = definitions.iter().map(|def| let serial_names: Vec<Option<token::InternedString>> =
find_serial_name(def.node.attrs.iter()) definitions.iter().map(|def|
).collect(); find_serial_name(def.node.attrs.iter())
).collect();
let struct_block = deserialize_struct_from_struct( let struct_block = deserialize_struct_from_struct(
cx, cx,
span, span,
type_ident, type_ident,
serial_names, serial_names.as_slice(),
fields, fields,
deserializer deserializer
); );
@ -308,6 +309,7 @@ fn deserialize_struct(
cx, cx,
span, span,
type_ident, type_ident,
serial_names.as_slice(),
fields, fields,
deserializer deserializer
); );
@ -332,7 +334,7 @@ fn deserialize_struct_from_struct(
cx: &ExtCtxt, cx: &ExtCtxt,
span: Span, span: Span,
type_ident: Ident, type_ident: Ident,
serial_names: Vec<Option<token::InternedString>>, serial_names: &[Option<token::InternedString>],
fields: &StaticFields, fields: &StaticFields,
deserializer: Gc<ast::Expr> deserializer: Gc<ast::Expr>
) -> Gc<ast::Expr> { ) -> Gc<ast::Expr> {
@ -364,6 +366,7 @@ fn deserialize_struct_from_map(
cx: &ExtCtxt, cx: &ExtCtxt,
span: Span, span: Span,
type_ident: Ident, type_ident: Ident,
serial_names: &[Option<token::InternedString>],
fields: &StaticFields, fields: &StaticFields,
deserializer: Gc<ast::Expr> deserializer: Gc<ast::Expr>
) -> Gc<ast::Expr> { ) -> Gc<ast::Expr> {
@ -380,9 +383,14 @@ fn deserialize_struct_from_map(
.collect(); .collect();
// Declare key arms. // Declare key arms.
let key_arms: Vec<ast::Arm> = fields.iter() let key_arms: Vec<ast::Arm> = serial_names.iter()
.map(|&(name, span)| { .zip(fields.iter())
let s = cx.expr_str(span, token::get_ident(name)); .map(|(serial, &(name, span))| {
let serial_name = match serial {
&Some(ref string) => string.clone(),
&None => token::get_ident(name),
};
let s = cx.expr_str(span, serial_name);
quote_arm!(cx, quote_arm!(cx,
$s => { $s => {
$name = Some( $name = Some(
@ -393,9 +401,14 @@ fn deserialize_struct_from_map(
}) })
.collect(); .collect();
let extract_fields: Vec<Gc<ast::Stmt>> = fields.iter() let extract_fields: Vec<Gc<ast::Stmt>> = serial_names.iter()
.map(|&(name, span)| { .zip(fields.iter())
let name_str = cx.expr_str(span, token::get_ident(name)); .map(|(serial, &(name, span))| {
let serial_name = match serial {
&Some(ref string) => string.clone(),
&None => token::get_ident(name),
};
let name_str = cx.expr_str(span, serial_name);
quote_stmt!(cx, quote_stmt!(cx,
let $name = match $name { let $name = match $name {
Some($name) => $name, Some($name) => $name,

31
tests/json_struct.rs Normal file
View File

@ -0,0 +1,31 @@
#![feature(phase)]
extern crate serde;
#[phase(plugin)]
extern crate serde_macros;
#[deriving(PartialEq, Show)]
#[deriving_serializable]
#[deriving_deserializable]
struct Test {
#[serial_name = "$schema"]
schema: String,
title: String,
#[serial_name = "type"]
ty: int
}
#[test]
fn test_json_struct() {
let input = Test {
schema: "a".to_string(),
title: "b".to_string(),
ty: 3,
};
let s = serde::json::to_string(&input).unwrap();
assert_eq!(s.as_slice(), r#"{"$schema":"a","title":"b","type":3}"#);
let output: Test = serde::json::from_str(s.as_slice()).unwrap();
assert_eq!(input, output);
}