Meaningful spans when invoking serializer trait methods
This commit is contained in:
parent
5c41661bce
commit
cc2558b0dc
@ -7,6 +7,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
use syn::{self, Ident, Index, Member};
|
||||
use syn::spanned::Spanned;
|
||||
use quote::Tokens;
|
||||
use proc_macro2::Span;
|
||||
|
||||
@ -211,8 +212,10 @@ fn serialize_newtype_struct(
|
||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
||||
}
|
||||
|
||||
let span = Span::def_site().located_at(field.original.span());
|
||||
let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_struct);
|
||||
quote_expr! {
|
||||
_serde::Serializer::serialize_newtype_struct(__serializer, #type_name, #field_expr)
|
||||
#func(__serializer, #type_name, #field_expr)
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +228,7 @@ fn serialize_tuple_struct(
|
||||
fields,
|
||||
params,
|
||||
false,
|
||||
"e!(_serde::ser::SerializeTupleStruct::serialize_field),
|
||||
&TupleTrait::SerializeTupleStruct,
|
||||
);
|
||||
|
||||
let type_name = cattrs.name().serialize_name();
|
||||
@ -246,8 +249,7 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
|
||||
fields,
|
||||
params,
|
||||
false,
|
||||
"e!(_serde::ser::SerializeStruct::serialize_field),
|
||||
"e!(_serde::ser::SerializeStruct::skip_field),
|
||||
&StructTrait::SerializeStruct,
|
||||
);
|
||||
|
||||
let type_name = cattrs.name().serialize_name();
|
||||
@ -670,14 +672,12 @@ fn serialize_tuple_variant(
|
||||
params: &Parameters,
|
||||
fields: &[Field],
|
||||
) -> Fragment {
|
||||
let method = match context {
|
||||
TupleVariant::ExternallyTagged { .. } => {
|
||||
quote!(_serde::ser::SerializeTupleVariant::serialize_field)
|
||||
}
|
||||
TupleVariant::Untagged => quote!(_serde::ser::SerializeTuple::serialize_element),
|
||||
let tuple_trait = match context {
|
||||
TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant,
|
||||
TupleVariant::Untagged => TupleTrait::SerializeTuple,
|
||||
};
|
||||
|
||||
let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &method);
|
||||
let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait);
|
||||
|
||||
let len = serialize_stmts.len();
|
||||
let let_mut = mut_if(len > 0);
|
||||
@ -729,18 +729,16 @@ fn serialize_struct_variant<'a>(
|
||||
fields: &[Field],
|
||||
name: &str,
|
||||
) -> Fragment {
|
||||
let (method, skip_method) = match context {
|
||||
let struct_trait = match context {
|
||||
StructVariant::ExternallyTagged { .. } => (
|
||||
quote!(_serde::ser::SerializeStructVariant::serialize_field),
|
||||
quote!(_serde::ser::SerializeStructVariant::skip_field),
|
||||
StructTrait::SerializeStructVariant
|
||||
),
|
||||
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => (
|
||||
quote!(_serde::ser::SerializeStruct::serialize_field),
|
||||
quote!(_serde::ser::SerializeStruct::skip_field),
|
||||
StructTrait::SerializeStruct
|
||||
),
|
||||
};
|
||||
|
||||
let serialize_fields = serialize_struct_visitor(fields, params, true, &method, &skip_method);
|
||||
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
|
||||
|
||||
let mut serialized_fields = fields
|
||||
.iter()
|
||||
@ -811,7 +809,7 @@ fn serialize_tuple_struct_visitor(
|
||||
fields: &[Field],
|
||||
params: &Parameters,
|
||||
is_enum: bool,
|
||||
func: &Tokens,
|
||||
tuple_trait: &TupleTrait,
|
||||
) -> Vec<Tokens> {
|
||||
fields
|
||||
.iter()
|
||||
@ -836,6 +834,8 @@ fn serialize_tuple_struct_visitor(
|
||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
||||
}
|
||||
|
||||
let span = Span::def_site().located_at(field.original.span());
|
||||
let func = tuple_trait.serialize_element(span);
|
||||
let ser = quote! {
|
||||
try!(#func(&mut __serde_state, #field_expr));
|
||||
};
|
||||
@ -852,8 +852,7 @@ fn serialize_struct_visitor(
|
||||
fields: &[Field],
|
||||
params: &Parameters,
|
||||
is_enum: bool,
|
||||
func: &Tokens,
|
||||
skip_func: &Tokens,
|
||||
struct_trait: &StructTrait,
|
||||
) -> Vec<Tokens> {
|
||||
fields
|
||||
.iter()
|
||||
@ -877,6 +876,8 @@ fn serialize_struct_visitor(
|
||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
||||
}
|
||||
|
||||
let span = Span::def_site().located_at(field.original.span());
|
||||
let func = struct_trait.serialize_field(span);
|
||||
let ser = quote! {
|
||||
try!(#func(&mut __serde_state, #key_expr, #field_expr));
|
||||
};
|
||||
@ -884,6 +885,7 @@ fn serialize_struct_visitor(
|
||||
match skip {
|
||||
None => ser,
|
||||
Some(skip) => {
|
||||
let skip_func = struct_trait.skip_field(span);
|
||||
quote! {
|
||||
if !#skip {
|
||||
#ser
|
||||
@ -1007,3 +1009,54 @@ fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum StructTrait {
|
||||
SerializeStruct,
|
||||
SerializeStructVariant,
|
||||
}
|
||||
|
||||
impl StructTrait {
|
||||
fn serialize_field(&self, span: Span) -> Tokens {
|
||||
match *self {
|
||||
StructTrait::SerializeStruct => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field)
|
||||
}
|
||||
StructTrait::SerializeStructVariant => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_field(&self, span: Span) -> Tokens {
|
||||
match *self {
|
||||
StructTrait::SerializeStruct => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field)
|
||||
}
|
||||
StructTrait::SerializeStructVariant => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TupleTrait {
|
||||
SerializeTuple,
|
||||
SerializeTupleStruct,
|
||||
SerializeTupleVariant,
|
||||
}
|
||||
|
||||
impl TupleTrait {
|
||||
fn serialize_element(&self, span: Span) -> Tokens {
|
||||
match *self {
|
||||
TupleTrait::SerializeTuple => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element)
|
||||
}
|
||||
TupleTrait::SerializeTupleStruct => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field)
|
||||
}
|
||||
TupleTrait::SerializeTupleVariant => {
|
||||
quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ pub struct Field<'a> {
|
||||
pub ident: Option<syn::Ident>,
|
||||
pub attrs: attr::Field,
|
||||
pub ty: &'a syn::Type,
|
||||
pub original: &'a syn::Field,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
@ -157,6 +158,7 @@ fn fields_from_ast<'a>(
|
||||
ident: field.ident,
|
||||
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
|
||||
ty: &field.ty,
|
||||
original: &field,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user