Switch to using MultiDecorator

This commit is contained in:
Erick Tryzelaar 2015-05-17 23:14:38 -07:00
parent 482f92af61
commit 2c24be90d2
3 changed files with 77 additions and 59 deletions

View File

@ -1,6 +1,9 @@
use std::collections::HashSet;
use aster;
use syntax::ast::{
self,
Ident,
MetaItem,
Item,
@ -8,25 +11,32 @@ use syntax::ast::{
StructDef,
EnumDef,
};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::owned_slice::OwnedSlice;
use syntax::ptr::P;
use aster;
use attr;
use field;
pub fn expand_derive_deserialize(
cx: &mut ExtCtxt,
span: Span,
_mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<ast::Item>)
meta_item: &MetaItem,
annotatable: Annotatable,
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 generics = match item.node {
@ -48,7 +58,7 @@ pub fn expand_derive_deserialize(
let body = deserialize_body(
cx,
&builder,
item,
&item,
&impl_generics,
ty.clone(),
);
@ -66,7 +76,7 @@ pub fn expand_derive_deserialize(
}
).unwrap();
push(impl_item)
push(Annotatable::Item(impl_item))
}
fn deserialize_body(
@ -661,49 +671,47 @@ fn deserialize_field_visitor(
})
};
vec![
field_enum,
let impl_item = quote_item!(cx,
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,
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;
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 })
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 })
}
).unwrap(),
]
}
).unwrap();
vec![field_enum, impl_item]
}
fn deserialize_struct_visitor(

View File

@ -14,11 +14,11 @@ mod ser;
pub fn register(reg: &mut rustc::plugin::Registry) {
reg.register_syntax_extension(
syntax::parse::token::intern("derive_Serialize"),
syntax::ext::base::Decorator(
syntax::ext::base::MultiDecorator(
Box::new(ser::expand_derive_serialize)));
reg.register_syntax_extension(
syntax::parse::token::intern("derive_Deserialize"),
syntax::ext::base::Decorator(
syntax::ext::base::MultiDecorator(
Box::new(de::expand_derive_deserialize)));
}

View File

@ -1,3 +1,5 @@
use aster;
use syntax::ast::{
Ident,
MetaItem,
@ -7,21 +9,29 @@ use syntax::ast::{
};
use syntax::ast;
use syntax::codemap::Span;
use syntax::ext::base::ExtCtxt;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ext::build::AstBuilder;
use syntax::ptr::P;
use aster;
use field::struct_field_attrs;
pub fn expand_derive_serialize(
cx: &mut ExtCtxt,
span: Span,
_mitem: &MetaItem,
item: &Item,
push: &mut FnMut(P<ast::Item>)
meta_item: &MetaItem,
annotatable: Annotatable,
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 generics = match item.node {
@ -43,7 +53,7 @@ pub fn expand_derive_serialize(
let body = serialize_body(
cx,
&builder,
item,
&item,
&impl_generics,
ty.clone(),
);
@ -61,7 +71,7 @@ pub fn expand_derive_serialize(
}
).unwrap();
push(impl_item)
push(Annotatable::Item(impl_item))
}
fn serialize_body(