Inform serializers about skipped fields.

Closes #960.
This commit is contained in:
Steven Fackler 2017-08-19 10:29:54 -07:00 committed by Steven Fackler
parent d4042872f5
commit 2fe9a860cd
2 changed files with 35 additions and 5 deletions

View File

@ -1727,6 +1727,12 @@ pub trait SerializeStruct {
where where
T: Serialize; T: Serialize;
/// Indicate that a struct field has been skipped.
fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
let _ = key;
Ok(())
}
/// Finish serializing a struct. /// Finish serializing a struct.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }
@ -1772,6 +1778,12 @@ pub trait SerializeStructVariant {
where where
T: Serialize; T: Serialize;
/// Indicate that a struct variant field has been skipped.
fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
let _ = key;
Ok(())
}
/// Finish serializing a struct variant. /// Finish serializing a struct variant.
fn end(self) -> Result<Self::Ok, Self::Error>; fn end(self) -> Result<Self::Ok, Self::Error>;
} }

View File

@ -242,6 +242,7 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
params, params,
false, false,
quote!(_serde::ser::SerializeStruct::serialize_field), quote!(_serde::ser::SerializeStruct::serialize_field),
quote!(_serde::ser::SerializeStruct::skip_field),
); );
let type_name = cattrs.name().serialize_name(); let type_name = cattrs.name().serialize_name();
@ -707,15 +708,23 @@ fn serialize_struct_variant<'a>(
fields: &[Field], fields: &[Field],
name: &str, name: &str,
) -> Fragment { ) -> Fragment {
let method = match context { let (method, skip_method) = match context {
StructVariant::ExternallyTagged { .. } => { StructVariant::ExternallyTagged { .. } => {
quote!(_serde::ser::SerializeStructVariant::serialize_field) (
quote!(_serde::ser::SerializeStructVariant::serialize_field),
quote!(_serde::ser::SerializeStructVariant::skip_field),
)
} }
StructVariant::InternallyTagged { .. } | StructVariant::InternallyTagged { .. } |
StructVariant::Untagged => quote!(_serde::ser::SerializeStruct::serialize_field), StructVariant::Untagged => {
(
quote!(_serde::ser::SerializeStruct::serialize_field),
quote!(_serde::ser::SerializeStruct::skip_field),
)
}
}; };
let serialize_fields = serialize_struct_visitor(fields, params, true, method); let serialize_fields = serialize_struct_visitor(fields, params, true, method, skip_method);
let mut serialized_fields = fields let mut serialized_fields = fields
.iter() .iter()
@ -829,6 +838,7 @@ fn serialize_struct_visitor(
params: &Parameters, params: &Parameters,
is_enum: bool, is_enum: bool,
func: Tokens, func: Tokens,
skip_func: Tokens,
) -> Vec<Tokens> { ) -> Vec<Tokens> {
fields fields
.iter() .iter()
@ -859,7 +869,15 @@ fn serialize_struct_visitor(
match skip { match skip {
None => ser, None => ser,
Some(skip) => quote!(if !#skip { #ser }), Some(skip) => {
quote! {
if !#skip {
#ser
} else {
try!(#skip_func(&mut __serde_state, #key_expr));
}
}
}
} }
}, },
) )