mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-02 15:25:38 +00:00
Factor out logic to decide the tag style
This commit is contained in:
parent
f9535a4d67
commit
a35bde49c6
@ -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 {
|
Container {
|
||||||
name: Name {
|
name: Name {
|
||||||
serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
|
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),
|
rename_all: rename_all.get().unwrap_or(RenameRule::None),
|
||||||
ser_bound: ser_bound.get(),
|
ser_bound: ser_bound.get(),
|
||||||
de_bound: de_bound.get(),
|
de_bound: de_bound.get(),
|
||||||
tag: tag,
|
tag: decide_tag(cx, item, untagged, internal_tag, content),
|
||||||
from_type: from_type.get(),
|
from_type: from_type.get(),
|
||||||
into_type: into_type.get(),
|
into_type: into_type.get(),
|
||||||
remote: remote.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
|
/// Represents variant attribute information
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Variant {
|
pub struct Variant {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user