Simplify generated visitors

This commit is contained in:
David Tolnay 2016-08-03 19:53:41 -07:00
parent b289edd4a4
commit d5102a7afd
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82

View File

@ -192,31 +192,24 @@ fn deserialize_body(
// Build `__Visitor<A, B, ...>(PhantomData<A>, PhantomData<B>, ...)` // Build `__Visitor<A, B, ...>(PhantomData<A>, PhantomData<B>, ...)`
fn deserialize_visitor( fn deserialize_visitor(
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
trait_generics: &ast::Generics, generics: &ast::Generics,
forward_ty_params: Vec<ast::TyParam>, ) -> (P<ast::Item>, P<ast::Ty>, P<ast::Expr>) {
forward_tys: Vec<P<ast::Ty>> if generics.ty_params.is_empty() {
) -> (P<ast::Item>, P<ast::Ty>, P<ast::Expr>, ast::Generics) {
if trait_generics.ty_params.is_empty() && forward_tys.is_empty() {
( (
builder.item().tuple_struct("__Visitor").build(), builder.item().unit_struct("__Visitor"),
builder.ty().id("__Visitor"), builder.ty().id("__Visitor"),
builder.expr().id("__Visitor"), builder.expr().id("__Visitor"),
trait_generics.clone(),
) )
} else { } else {
let placeholders : Vec<_> = trait_generics.ty_params.iter() let placeholders : Vec<_> = generics.ty_params.iter()
.map(|t| builder.ty().id(t.ident)) .map(|t| builder.ty().id(t.ident))
.collect(); .collect();
let mut trait_generics = trait_generics.clone();
let mut ty_params = forward_ty_params.clone();
ty_params.extend(trait_generics.ty_params.into_vec());
trait_generics.ty_params = P::from_vec(ty_params);
( (
builder.item().tuple_struct("__Visitor") builder.item().tuple_struct("__Visitor")
.generics().with(trait_generics.clone()).build() .generics().with(generics.clone()).build()
.with_tys({ .with_tys({
let lifetimes = trait_generics.lifetimes.iter() let lifetimes = generics.lifetimes.iter()
.map(|lifetime_def| { .map(|lifetime_def| {
builder.ty() builder.ty()
.phantom_data() .phantom_data()
@ -225,7 +218,7 @@ fn deserialize_visitor(
.unit() .unit()
}); });
let ty_params = trait_generics.ty_params.iter() let ty_params = generics.ty_params.iter()
.map(|ty_param| { .map(|ty_param| {
builder.ty() builder.ty()
.phantom_data() .phantom_data()
@ -236,39 +229,22 @@ fn deserialize_visitor(
}) })
.build(), .build(),
builder.ty().path() builder.ty().path()
.segment("__Visitor").with_generics(trait_generics.clone()).build() .segment("__Visitor").with_generics(generics.clone()).build()
.build(), .build(),
builder.expr().call() builder.expr().call()
.path().segment("__Visitor") .path().segment("__Visitor")
.with_tys(forward_tys)
.with_tys(placeholders) .with_tys(placeholders)
.build().build() .build().build()
.with_args({ .with_args({
let len = trait_generics.lifetimes.len() + trait_generics.ty_params.len(); let len = generics.lifetimes.len() + generics.ty_params.len();
(0 .. len).map(|_| builder.expr().phantom_data()) (0 .. len).map(|_| builder.expr().phantom_data())
}) })
.build(), .build(),
trait_generics,
) )
} }
} }
fn deserializer_ty_param(builder: &aster::AstBuilder) -> ast::TyParam {
builder.ty_param("__D")
.trait_bound(builder.path()
.segment("_serde").build()
.segment("de").build()
.id("Deserializer")
.build())
.build()
.build()
}
fn deserializer_ty_arg(builder: &aster::AstBuilder) -> P<ast::Ty>{
builder.ty().id("__D")
}
fn deserialize_unit_struct( fn deserialize_unit_struct(
cx: &ExtCtxt, cx: &ExtCtxt,
builder: &aster::AstBuilder, builder: &aster::AstBuilder,
@ -315,11 +291,9 @@ fn deserialize_tuple(
) -> P<ast::Expr> { ) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause; let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) = deserialize_visitor( let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder, builder,
impl_generics, impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
); );
let is_enum = variant_ident.is_some(); let is_enum = variant_ident.is_some();
@ -369,7 +343,7 @@ fn deserialize_tuple(
quote_expr!(cx, { quote_expr!(cx, {
$visitor_item $visitor_item
impl $visitor_generics _serde::de::Visitor for $visitor_ty $where_clause { impl $impl_generics _serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty; type Value = $ty;
$visit_newtype_struct $visit_newtype_struct
@ -516,11 +490,9 @@ fn deserialize_struct(
) -> P<ast::Expr> { ) -> P<ast::Expr> {
let where_clause = &impl_generics.where_clause; let where_clause = &impl_generics.where_clause;
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) = deserialize_visitor( let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder, builder,
&impl_generics, impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
); );
let type_path = match variant_ident { let type_path = match variant_ident {
@ -563,7 +535,7 @@ fn deserialize_struct(
$visitor_item $visitor_item
impl $visitor_generics _serde::de::Visitor for $visitor_ty $where_clause { impl $impl_generics _serde::de::Visitor for $visitor_ty $where_clause {
type Value = $ty; type Value = $ty;
#[inline] #[inline]
@ -648,11 +620,9 @@ fn deserialize_item_enum(
} }
variant_arms.extend(ignored_arm.into_iter()); variant_arms.extend(ignored_arm.into_iter());
let (visitor_item, visitor_ty, visitor_expr, visitor_generics) = deserialize_visitor( let (visitor_item, visitor_ty, visitor_expr) = deserialize_visitor(
builder, builder,
impl_generics, impl_generics,
vec![deserializer_ty_param(builder)],
vec![deserializer_ty_arg(builder)],
); );
quote_expr!(cx, { quote_expr!(cx, {
@ -660,7 +630,7 @@ fn deserialize_item_enum(
$visitor_item $visitor_item
impl $visitor_generics _serde::de::EnumVisitor for $visitor_ty $where_clause { impl $impl_generics _serde::de::EnumVisitor for $visitor_ty $where_clause {
type Value = $ty; type Value = $ty;
fn visit<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error> fn visit<__V>(&mut self, mut visitor: __V) -> ::std::result::Result<$ty, __V::Error>
@ -879,13 +849,9 @@ fn deserialize_field_visitor(
fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<__Field, __D::Error> fn deserialize<__D>(deserializer: &mut __D) -> ::std::result::Result<__Field, __D::Error>
where __D: _serde::de::Deserializer, where __D: _serde::de::Deserializer,
{ {
struct __FieldVisitor<__D> { struct __FieldVisitor;
phantom: ::std::marker::PhantomData<__D>
}
impl<__D> _serde::de::Visitor for __FieldVisitor<__D> impl _serde::de::Visitor for __FieldVisitor {
where __D: _serde::de::Deserializer
{
type Value = __Field; type Value = __Field;
fn visit_usize<__E>(&mut self, value: usize) -> ::std::result::Result<__Field, __E> fn visit_usize<__E>(&mut self, value: usize) -> ::std::result::Result<__Field, __E>
@ -907,11 +873,7 @@ fn deserialize_field_visitor(
} }
} }
deserializer.deserialize_struct_field( deserializer.deserialize_struct_field(__FieldVisitor)
__FieldVisitor::<__D>{
phantom: ::std::marker::PhantomData
}
)
} }
} }
).unwrap(); ).unwrap();