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.
|
// except according to those terms.
|
||||||
|
|
||||||
use syn::{self, Ident, Index, Member};
|
use syn::{self, Ident, Index, Member};
|
||||||
|
use syn::spanned::Spanned;
|
||||||
use quote::Tokens;
|
use quote::Tokens;
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
|
|
||||||
@ -211,8 +212,10 @@ fn serialize_newtype_struct(
|
|||||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
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! {
|
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,
|
fields,
|
||||||
params,
|
params,
|
||||||
false,
|
false,
|
||||||
"e!(_serde::ser::SerializeTupleStruct::serialize_field),
|
&TupleTrait::SerializeTupleStruct,
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_name = cattrs.name().serialize_name();
|
let type_name = cattrs.name().serialize_name();
|
||||||
@ -246,8 +249,7 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
|
|||||||
fields,
|
fields,
|
||||||
params,
|
params,
|
||||||
false,
|
false,
|
||||||
"e!(_serde::ser::SerializeStruct::serialize_field),
|
&StructTrait::SerializeStruct,
|
||||||
"e!(_serde::ser::SerializeStruct::skip_field),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let type_name = cattrs.name().serialize_name();
|
let type_name = cattrs.name().serialize_name();
|
||||||
@ -670,14 +672,12 @@ fn serialize_tuple_variant(
|
|||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let method = match context {
|
let tuple_trait = match context {
|
||||||
TupleVariant::ExternallyTagged { .. } => {
|
TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant,
|
||||||
quote!(_serde::ser::SerializeTupleVariant::serialize_field)
|
TupleVariant::Untagged => TupleTrait::SerializeTuple,
|
||||||
}
|
|
||||||
TupleVariant::Untagged => quote!(_serde::ser::SerializeTuple::serialize_element),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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 len = serialize_stmts.len();
|
||||||
let let_mut = mut_if(len > 0);
|
let let_mut = mut_if(len > 0);
|
||||||
@ -729,18 +729,16 @@ fn serialize_struct_variant<'a>(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
name: &str,
|
name: &str,
|
||||||
) -> Fragment {
|
) -> Fragment {
|
||||||
let (method, skip_method) = match context {
|
let struct_trait = match context {
|
||||||
StructVariant::ExternallyTagged { .. } => (
|
StructVariant::ExternallyTagged { .. } => (
|
||||||
quote!(_serde::ser::SerializeStructVariant::serialize_field),
|
StructTrait::SerializeStructVariant
|
||||||
quote!(_serde::ser::SerializeStructVariant::skip_field),
|
|
||||||
),
|
),
|
||||||
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => (
|
StructVariant::InternallyTagged { .. } | StructVariant::Untagged => (
|
||||||
quote!(_serde::ser::SerializeStruct::serialize_field),
|
StructTrait::SerializeStruct
|
||||||
quote!(_serde::ser::SerializeStruct::skip_field),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
let mut serialized_fields = fields
|
||||||
.iter()
|
.iter()
|
||||||
@ -811,7 +809,7 @@ fn serialize_tuple_struct_visitor(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
is_enum: bool,
|
is_enum: bool,
|
||||||
func: &Tokens,
|
tuple_trait: &TupleTrait,
|
||||||
) -> Vec<Tokens> {
|
) -> Vec<Tokens> {
|
||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
@ -836,6 +834,8 @@ fn serialize_tuple_struct_visitor(
|
|||||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
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! {
|
let ser = quote! {
|
||||||
try!(#func(&mut __serde_state, #field_expr));
|
try!(#func(&mut __serde_state, #field_expr));
|
||||||
};
|
};
|
||||||
@ -852,8 +852,7 @@ fn serialize_struct_visitor(
|
|||||||
fields: &[Field],
|
fields: &[Field],
|
||||||
params: &Parameters,
|
params: &Parameters,
|
||||||
is_enum: bool,
|
is_enum: bool,
|
||||||
func: &Tokens,
|
struct_trait: &StructTrait,
|
||||||
skip_func: &Tokens,
|
|
||||||
) -> Vec<Tokens> {
|
) -> Vec<Tokens> {
|
||||||
fields
|
fields
|
||||||
.iter()
|
.iter()
|
||||||
@ -877,6 +876,8 @@ fn serialize_struct_visitor(
|
|||||||
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
|
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! {
|
let ser = quote! {
|
||||||
try!(#func(&mut __serde_state, #key_expr, #field_expr));
|
try!(#func(&mut __serde_state, #key_expr, #field_expr));
|
||||||
};
|
};
|
||||||
@ -884,6 +885,7 @@ fn serialize_struct_visitor(
|
|||||||
match skip {
|
match skip {
|
||||||
None => ser,
|
None => ser,
|
||||||
Some(skip) => {
|
Some(skip) => {
|
||||||
|
let skip_func = struct_trait.skip_field(span);
|
||||||
quote! {
|
quote! {
|
||||||
if !#skip {
|
if !#skip {
|
||||||
#ser
|
#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 ident: Option<syn::Ident>,
|
||||||
pub attrs: attr::Field,
|
pub attrs: attr::Field,
|
||||||
pub ty: &'a syn::Type,
|
pub ty: &'a syn::Type,
|
||||||
|
pub original: &'a syn::Field,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -157,6 +158,7 @@ fn fields_from_ast<'a>(
|
|||||||
ident: field.ident,
|
ident: field.ident,
|
||||||
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
|
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
|
||||||
ty: &field.ty,
|
ty: &field.ty,
|
||||||
|
original: &field,
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user