mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-12 15:31:07 +00:00
Switch to using MultiDecorator
This commit is contained in:
+57
-49
@@ -1,6 +1,9 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use aster;
|
||||||
|
|
||||||
use syntax::ast::{
|
use syntax::ast::{
|
||||||
|
self,
|
||||||
Ident,
|
Ident,
|
||||||
MetaItem,
|
MetaItem,
|
||||||
Item,
|
Item,
|
||||||
@@ -8,25 +11,32 @@ use syntax::ast::{
|
|||||||
StructDef,
|
StructDef,
|
||||||
EnumDef,
|
EnumDef,
|
||||||
};
|
};
|
||||||
use syntax::ast;
|
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::ExtCtxt;
|
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::owned_slice::OwnedSlice;
|
use syntax::owned_slice::OwnedSlice;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
use aster;
|
|
||||||
|
|
||||||
use attr;
|
use attr;
|
||||||
use field;
|
use field;
|
||||||
|
|
||||||
pub fn expand_derive_deserialize(
|
pub fn expand_derive_deserialize(
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
_mitem: &MetaItem,
|
meta_item: &MetaItem,
|
||||||
item: &Item,
|
annotatable: Annotatable,
|
||||||
push: &mut FnMut(P<ast::Item>)
|
push: &mut FnMut(Annotatable)
|
||||||
) {
|
) {
|
||||||
|
let item = match annotatable {
|
||||||
|
Annotatable::Item(item) => item,
|
||||||
|
_ => {
|
||||||
|
cx.span_err(
|
||||||
|
meta_item.span,
|
||||||
|
"`derive` may only be applied to structs and enums");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let builder = aster::AstBuilder::new().span(span);
|
let builder = aster::AstBuilder::new().span(span);
|
||||||
|
|
||||||
let generics = match item.node {
|
let generics = match item.node {
|
||||||
@@ -48,7 +58,7 @@ pub fn expand_derive_deserialize(
|
|||||||
let body = deserialize_body(
|
let body = deserialize_body(
|
||||||
cx,
|
cx,
|
||||||
&builder,
|
&builder,
|
||||||
item,
|
&item,
|
||||||
&impl_generics,
|
&impl_generics,
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
);
|
);
|
||||||
@@ -66,7 +76,7 @@ pub fn expand_derive_deserialize(
|
|||||||
}
|
}
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
push(impl_item)
|
push(Annotatable::Item(impl_item))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_body(
|
fn deserialize_body(
|
||||||
@@ -661,49 +671,47 @@ fn deserialize_field_visitor(
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
vec![
|
let impl_item = quote_item!(cx,
|
||||||
field_enum,
|
impl ::serde::de::Deserialize for __Field {
|
||||||
|
#[inline]
|
||||||
|
fn deserialize<D>(deserializer: &mut D) -> ::std::result::Result<__Field, D::Error>
|
||||||
|
where D: ::serde::de::Deserializer,
|
||||||
|
{
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
quote_item!(cx,
|
struct __FieldVisitor<D> {
|
||||||
impl ::serde::de::Deserialize for __Field {
|
phantom: PhantomData<D>
|
||||||
#[inline]
|
|
||||||
fn deserialize<D>(deserializer: &mut D) -> ::std::result::Result<__Field, D::Error>
|
|
||||||
where D: ::serde::de::Deserializer,
|
|
||||||
{
|
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
|
||||||
struct __FieldVisitor<D> {
|
|
||||||
phantom: PhantomData<D>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<__D> ::serde::de::Visitor for __FieldVisitor<__D>
|
|
||||||
where __D: ::serde::de::Deserializer
|
|
||||||
{
|
|
||||||
type Value = __Field;
|
|
||||||
|
|
||||||
fn visit_str<E>(&mut self, value: &str) -> ::std::result::Result<__Field, E>
|
|
||||||
where E: ::serde::de::Error,
|
|
||||||
{
|
|
||||||
$body
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_bytes<E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, E>
|
|
||||||
where E: ::serde::de::Error,
|
|
||||||
{
|
|
||||||
// TODO: would be better to generate a byte string literal match
|
|
||||||
match ::std::str::from_utf8(value) {
|
|
||||||
Ok(s) => self.visit_str(s),
|
|
||||||
_ => Err(::serde::de::Error::syntax_error()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.visit(
|
|
||||||
__FieldVisitor::<D>{ phantom: PhantomData })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<__D> ::serde::de::Visitor for __FieldVisitor<__D>
|
||||||
|
where __D: ::serde::de::Deserializer
|
||||||
|
{
|
||||||
|
type Value = __Field;
|
||||||
|
|
||||||
|
fn visit_str<E>(&mut self, value: &str) -> ::std::result::Result<__Field, E>
|
||||||
|
where E: ::serde::de::Error,
|
||||||
|
{
|
||||||
|
$body
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_bytes<E>(&mut self, value: &[u8]) -> ::std::result::Result<__Field, E>
|
||||||
|
where E: ::serde::de::Error,
|
||||||
|
{
|
||||||
|
// TODO: would be better to generate a byte string literal match
|
||||||
|
match ::std::str::from_utf8(value) {
|
||||||
|
Ok(s) => self.visit_str(s),
|
||||||
|
_ => Err(::serde::de::Error::syntax_error()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.visit(
|
||||||
|
__FieldVisitor::<D>{ phantom: PhantomData })
|
||||||
}
|
}
|
||||||
).unwrap(),
|
}
|
||||||
]
|
).unwrap();
|
||||||
|
|
||||||
|
vec![field_enum, impl_item]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_struct_visitor(
|
fn deserialize_struct_visitor(
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ mod ser;
|
|||||||
pub fn register(reg: &mut rustc::plugin::Registry) {
|
pub fn register(reg: &mut rustc::plugin::Registry) {
|
||||||
reg.register_syntax_extension(
|
reg.register_syntax_extension(
|
||||||
syntax::parse::token::intern("derive_Serialize"),
|
syntax::parse::token::intern("derive_Serialize"),
|
||||||
syntax::ext::base::Decorator(
|
syntax::ext::base::MultiDecorator(
|
||||||
Box::new(ser::expand_derive_serialize)));
|
Box::new(ser::expand_derive_serialize)));
|
||||||
|
|
||||||
reg.register_syntax_extension(
|
reg.register_syntax_extension(
|
||||||
syntax::parse::token::intern("derive_Deserialize"),
|
syntax::parse::token::intern("derive_Deserialize"),
|
||||||
syntax::ext::base::Decorator(
|
syntax::ext::base::MultiDecorator(
|
||||||
Box::new(de::expand_derive_deserialize)));
|
Box::new(de::expand_derive_deserialize)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use aster;
|
||||||
|
|
||||||
use syntax::ast::{
|
use syntax::ast::{
|
||||||
Ident,
|
Ident,
|
||||||
MetaItem,
|
MetaItem,
|
||||||
@@ -7,21 +9,29 @@ use syntax::ast::{
|
|||||||
};
|
};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ext::base::ExtCtxt;
|
use syntax::ext::base::{Annotatable, ExtCtxt};
|
||||||
use syntax::ext::build::AstBuilder;
|
use syntax::ext::build::AstBuilder;
|
||||||
use syntax::ptr::P;
|
use syntax::ptr::P;
|
||||||
|
|
||||||
use aster;
|
|
||||||
|
|
||||||
use field::struct_field_attrs;
|
use field::struct_field_attrs;
|
||||||
|
|
||||||
pub fn expand_derive_serialize(
|
pub fn expand_derive_serialize(
|
||||||
cx: &mut ExtCtxt,
|
cx: &mut ExtCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
_mitem: &MetaItem,
|
meta_item: &MetaItem,
|
||||||
item: &Item,
|
annotatable: Annotatable,
|
||||||
push: &mut FnMut(P<ast::Item>)
|
push: &mut FnMut(Annotatable)
|
||||||
) {
|
) {
|
||||||
|
let item = match annotatable {
|
||||||
|
Annotatable::Item(item) => item,
|
||||||
|
_ => {
|
||||||
|
cx.span_err(
|
||||||
|
meta_item.span,
|
||||||
|
"`derive` may only be applied to structs and enums");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let builder = aster::AstBuilder::new().span(span);
|
let builder = aster::AstBuilder::new().span(span);
|
||||||
|
|
||||||
let generics = match item.node {
|
let generics = match item.node {
|
||||||
@@ -43,7 +53,7 @@ pub fn expand_derive_serialize(
|
|||||||
let body = serialize_body(
|
let body = serialize_body(
|
||||||
cx,
|
cx,
|
||||||
&builder,
|
&builder,
|
||||||
item,
|
&item,
|
||||||
&impl_generics,
|
&impl_generics,
|
||||||
ty.clone(),
|
ty.clone(),
|
||||||
);
|
);
|
||||||
@@ -61,7 +71,7 @@ pub fn expand_derive_serialize(
|
|||||||
}
|
}
|
||||||
).unwrap();
|
).unwrap();
|
||||||
|
|
||||||
push(impl_item)
|
push(Annotatable::Item(impl_item))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_body(
|
fn serialize_body(
|
||||||
|
|||||||
Reference in New Issue
Block a user