diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index c565f0e7..cea5d05b 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -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) + 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(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(deserializer: &mut D) -> ::std::result::Result<__Field, D::Error> - where D: ::serde::de::Deserializer, - { - use std::marker::PhantomData; - - struct __FieldVisitor { - phantom: PhantomData - } - - impl<__D> ::serde::de::Visitor for __FieldVisitor<__D> - where __D: ::serde::de::Deserializer - { - type Value = __Field; - - fn visit_str(&mut self, value: &str) -> ::std::result::Result<__Field, E> - where E: ::serde::de::Error, - { - $body - } - - fn visit_bytes(&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::{ phantom: PhantomData }) + struct __FieldVisitor { + phantom: PhantomData } + + impl<__D> ::serde::de::Visitor for __FieldVisitor<__D> + where __D: ::serde::de::Deserializer + { + type Value = __Field; + + fn visit_str(&mut self, value: &str) -> ::std::result::Result<__Field, E> + where E: ::serde::de::Error, + { + $body + } + + fn visit_bytes(&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::{ phantom: PhantomData }) } - ).unwrap(), - ] + } + ).unwrap(); + + vec![field_enum, impl_item] } fn deserialize_struct_visitor( diff --git a/serde_codegen/src/lib.rs b/serde_codegen/src/lib.rs index 2e2d6018..8b6db0b2 100644 --- a/serde_codegen/src/lib.rs +++ b/serde_codegen/src/lib.rs @@ -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))); } diff --git a/serde_codegen/src/ser.rs b/serde_codegen/src/ser.rs index 70699d8d..0b046eaf 100644 --- a/serde_codegen/src/ser.rs +++ b/serde_codegen/src/ser.rs @@ -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) + 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(