Factor out logic to decide the tag style

This commit is contained in:
David Tolnay 2017-04-14 16:14:03 -07:00
parent f9535a4d67
commit a35bde49c6
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82

View File

@ -319,52 +319,6 @@ impl Container {
}
}
let tag = match (untagged.get(), internal_tag.get(), content.get()) {
(false, None, None) => EnumTag::External,
(true, None, None) => EnumTag::None,
(false, Some(tag), None) => {
// Check that there are no tuple variants.
if let syn::Body::Enum(ref variants) = item.body {
for variant in variants {
match variant.data {
syn::VariantData::Struct(_) |
syn::VariantData::Unit => {}
syn::VariantData::Tuple(ref fields) => {
if fields.len() != 1 {
cx.error("#[serde(tag = \"...\")] cannot be used with tuple \
variants");
break;
}
}
}
}
}
EnumTag::Internal { tag: tag }
}
(true, Some(_), None) => {
cx.error("enum cannot be both untagged and internally tagged");
EnumTag::External // doesn't matter, will error
}
(false, None, Some(_)) => {
cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
EnumTag::External
}
(true, None, Some(_)) => {
cx.error("untagged enum cannot have #[serde(content = \"...\")]");
EnumTag::External
}
(false, Some(tag), Some(content)) => {
EnumTag::Adjacent {
tag: tag,
content: content,
}
}
(true, Some(_), Some(_)) => {
cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
EnumTag::External
}
};
Container {
name: Name {
serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
@ -375,7 +329,7 @@ impl Container {
rename_all: rename_all.get().unwrap_or(RenameRule::None),
ser_bound: ser_bound.get(),
de_bound: de_bound.get(),
tag: tag,
tag: decide_tag(cx, item, untagged, internal_tag, content),
from_type: from_type.get(),
into_type: into_type.get(),
remote: remote.get(),
@ -423,6 +377,60 @@ impl Container {
}
}
fn decide_tag(
cx: &Ctxt,
item: &syn::MacroInput,
untagged: BoolAttr,
internal_tag: Attr<String>,
content: Attr<String>,
) -> EnumTag {
match (untagged.get(), internal_tag.get(), content.get()) {
(false, None, None) => EnumTag::External,
(true, None, None) => EnumTag::None,
(false, Some(tag), None) => {
// Check that there are no tuple variants.
if let syn::Body::Enum(ref variants) = item.body {
for variant in variants {
match variant.data {
syn::VariantData::Struct(_) |
syn::VariantData::Unit => {}
syn::VariantData::Tuple(ref fields) => {
if fields.len() != 1 {
cx.error("#[serde(tag = \"...\")] cannot be used with tuple \
variants");
break;
}
}
}
}
}
EnumTag::Internal { tag: tag }
}
(true, Some(_), None) => {
cx.error("enum cannot be both untagged and internally tagged");
EnumTag::External // doesn't matter, will error
}
(false, None, Some(_)) => {
cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
EnumTag::External
}
(true, None, Some(_)) => {
cx.error("untagged enum cannot have #[serde(content = \"...\")]");
EnumTag::External
}
(false, Some(tag), Some(content)) => {
EnumTag::Adjacent {
tag: tag,
content: content,
}
}
(true, Some(_), Some(_)) => {
cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
EnumTag::External
}
}
}
/// Represents variant attribute information
#[derive(Debug)]
pub struct Variant {