mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-02 15:25:38 +00:00
Implemented serial_name attribute
This commit is contained in:
parent
bc92cb884c
commit
394d0e987c
@ -10,14 +10,21 @@ extern crate rustc;
|
|||||||
use std::gc::Gc;
|
use std::gc::Gc;
|
||||||
|
|
||||||
use syntax::ast::{
|
use syntax::ast::{
|
||||||
|
Attribute,
|
||||||
Ident,
|
Ident,
|
||||||
MetaItem,
|
MetaItem,
|
||||||
|
MetaNameValue,
|
||||||
Item,
|
Item,
|
||||||
Expr,
|
Expr,
|
||||||
MutMutable,
|
MutMutable,
|
||||||
LitNil,
|
LitNil,
|
||||||
|
LitStr,
|
||||||
|
P,
|
||||||
|
StructField,
|
||||||
|
Variant,
|
||||||
};
|
};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
use syntax::attr;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::{ExtCtxt, ItemDecorator};
|
use syntax::ext::base::{ExtCtxt, ItemDecorator};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
@ -241,20 +248,22 @@ fn deserializable_substructure(cx: &mut ExtCtxt, span: Span,
|
|||||||
let token = substr.nonself_args[1];
|
let token = substr.nonself_args[1];
|
||||||
|
|
||||||
match *substr.fields {
|
match *substr.fields {
|
||||||
StaticStruct(_, ref fields) => {
|
StaticStruct(ref definition, ref fields) => {
|
||||||
deserialize_struct(
|
deserialize_struct(
|
||||||
cx,
|
cx,
|
||||||
span,
|
span,
|
||||||
substr.type_ident,
|
substr.type_ident,
|
||||||
|
definition.fields.as_slice(),
|
||||||
fields,
|
fields,
|
||||||
deserializer,
|
deserializer,
|
||||||
token)
|
token)
|
||||||
}
|
}
|
||||||
StaticEnum(_, ref fields) => {
|
StaticEnum(ref definition, ref fields) => {
|
||||||
deserialize_enum(
|
deserialize_enum(
|
||||||
cx,
|
cx,
|
||||||
span,
|
span,
|
||||||
substr.type_ident,
|
substr.type_ident,
|
||||||
|
definition.variants.as_slice(),
|
||||||
fields.as_slice(),
|
fields.as_slice(),
|
||||||
deserializer,
|
deserializer,
|
||||||
token)
|
token)
|
||||||
@ -263,18 +272,43 @@ fn deserializable_substructure(cx: &mut ExtCtxt, span: Span,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_serial_name<'a, I: Iterator<&'a Attribute>>(mut iterator: I)
|
||||||
|
-> Option<token::InternedString> {
|
||||||
|
for at in iterator {
|
||||||
|
match at.node.value.node {
|
||||||
|
MetaNameValue(ref at_name, ref value) => {
|
||||||
|
match (at_name.get(), &value.node) {
|
||||||
|
("serial_name", &LitStr(ref string, _)) => {
|
||||||
|
attr::mark_used(at);
|
||||||
|
return Some(string.clone());
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn deserialize_struct(
|
fn deserialize_struct(
|
||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
type_ident: Ident,
|
type_ident: Ident,
|
||||||
|
definitions: &[StructField],
|
||||||
fields: &StaticFields,
|
fields: &StaticFields,
|
||||||
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|
|
||||||
|
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,
|
||||||
fields,
|
fields,
|
||||||
deserializer
|
deserializer
|
||||||
);
|
);
|
||||||
@ -307,6 +341,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>>,
|
||||||
fields: &StaticFields,
|
fields: &StaticFields,
|
||||||
deserializer: Gc<ast::Expr>
|
deserializer: Gc<ast::Expr>
|
||||||
) -> Gc<ast::Expr> {
|
) -> Gc<ast::Expr> {
|
||||||
@ -316,6 +351,7 @@ fn deserialize_struct_from_struct(
|
|||||||
cx,
|
cx,
|
||||||
span,
|
span,
|
||||||
type_ident,
|
type_ident,
|
||||||
|
serial_names.as_slice(),
|
||||||
fields,
|
fields,
|
||||||
|cx, span, name| {
|
|cx, span, name| {
|
||||||
let name = cx.expr_str(span, name);
|
let name = cx.expr_str(span, name);
|
||||||
@ -428,12 +464,17 @@ fn deserialize_enum(
|
|||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
type_ident: Ident,
|
type_ident: Ident,
|
||||||
|
definitions: &[P<Variant>],
|
||||||
fields: &[(Ident, Span, StaticFields)],
|
fields: &[(Ident, Span, StaticFields)],
|
||||||
deserializer: Gc<ast::Expr>,
|
deserializer: Gc<ast::Expr>,
|
||||||
token: Gc<ast::Expr>
|
token: Gc<ast::Expr>
|
||||||
) -> Gc<ast::Expr> {
|
) -> Gc<ast::Expr> {
|
||||||
let type_name = cx.expr_str(span, token::get_ident(type_ident));
|
let type_name = cx.expr_str(span, token::get_ident(type_ident));
|
||||||
|
|
||||||
|
let serial_names = definitions.iter().map(|def|
|
||||||
|
find_serial_name(def.node.attrs.iter())
|
||||||
|
).collect::<Vec<Option<token::InternedString>>>();
|
||||||
|
|
||||||
let variants = fields.iter()
|
let variants = fields.iter()
|
||||||
.map(|&(name, span, _)| {
|
.map(|&(name, span, _)| {
|
||||||
cx.expr_str(span, token::get_ident(name))
|
cx.expr_str(span, token::get_ident(name))
|
||||||
@ -449,6 +490,7 @@ fn deserialize_enum(
|
|||||||
cx,
|
cx,
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
|
serial_names.as_slice(),
|
||||||
parts,
|
parts,
|
||||||
|cx, span, _| {
|
|cx, span, _| {
|
||||||
quote_expr!(cx, try!($deserializer.expect_enum_elt()))
|
quote_expr!(cx, try!($deserializer.expect_enum_elt()))
|
||||||
@ -480,6 +522,7 @@ fn deserializable_static_fields(
|
|||||||
cx: &ExtCtxt,
|
cx: &ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
outer_pat_ident: Ident,
|
outer_pat_ident: Ident,
|
||||||
|
serial_names: &[Option<token::InternedString>],
|
||||||
fields: &StaticFields,
|
fields: &StaticFields,
|
||||||
getarg: |&ExtCtxt, Span, token::InternedString| -> Gc<Expr>
|
getarg: |&ExtCtxt, Span, token::InternedString| -> Gc<Expr>
|
||||||
) -> Gc<Expr> {
|
) -> Gc<Expr> {
|
||||||
@ -501,11 +544,15 @@ fn deserializable_static_fields(
|
|||||||
}
|
}
|
||||||
Named(ref fields) => {
|
Named(ref fields) => {
|
||||||
// use the field's span to get nicer error messages.
|
// use the field's span to get nicer error messages.
|
||||||
let fields = fields.iter().map(|&(name, span)| {
|
let fields = serial_names.iter()
|
||||||
|
.zip(fields.iter()).map(|(serial_name, &(name, span))| {
|
||||||
|
let effective_name = serial_name.clone().unwrap_or(
|
||||||
|
token::get_ident(name)
|
||||||
|
);
|
||||||
let arg = getarg(
|
let arg = getarg(
|
||||||
cx,
|
cx,
|
||||||
span,
|
span,
|
||||||
token::get_ident(name)
|
effective_name
|
||||||
);
|
);
|
||||||
cx.field_imm(span, name, arg)
|
cx.field_imm(span, name, arg)
|
||||||
}).collect();
|
}).collect();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user