mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-20 02:11:04 +00:00
Allowed serde(tag="...") on structs
Added test test_internally_tagged_struct Renamed EnumTag to TagType as it now also used for structs Modified serialize_struct_as_struct
This commit is contained in:
@@ -120,7 +120,7 @@ pub struct Container {
|
||||
rename_all: RenameRule,
|
||||
ser_bound: Option<Vec<syn::WherePredicate>>,
|
||||
de_bound: Option<Vec<syn::WherePredicate>>,
|
||||
tag: EnumTag,
|
||||
tag: TagType,
|
||||
type_from: Option<syn::Type>,
|
||||
type_into: Option<syn::Type>,
|
||||
remote: Option<syn::Path>,
|
||||
@@ -129,7 +129,7 @@ pub struct Container {
|
||||
}
|
||||
|
||||
/// Styles of representing an enum.
|
||||
pub enum EnumTag {
|
||||
pub enum TagType {
|
||||
/// The default.
|
||||
///
|
||||
/// ```json
|
||||
@@ -358,17 +358,10 @@ impl Container {
|
||||
Meta(NameValue(ref m)) if m.ident == "tag" => {
|
||||
if let Ok(s) = get_lit_str(cx, &m.ident, &m.ident, &m.lit) {
|
||||
match item.data {
|
||||
syn::Data::Enum(_) => {
|
||||
syn::Data::Enum(_) |
|
||||
syn::Data::Struct(_, ..) => {
|
||||
internal_tag.set(&m.ident, s.value());
|
||||
}
|
||||
syn::Data::Struct(syn::DataStruct {
|
||||
ref struct_token, ..
|
||||
}) => {
|
||||
cx.error_spanned_by(
|
||||
struct_token,
|
||||
"#[serde(tag = \"...\")] can only be used on enums",
|
||||
);
|
||||
}
|
||||
syn::Data::Union(syn::DataUnion {
|
||||
ref union_token, ..
|
||||
}) => {
|
||||
@@ -505,7 +498,7 @@ impl Container {
|
||||
self.de_bound.as_ref().map(|vec| &vec[..])
|
||||
}
|
||||
|
||||
pub fn tag(&self) -> &EnumTag {
|
||||
pub fn tag(&self) -> &TagType {
|
||||
&self.tag
|
||||
}
|
||||
|
||||
@@ -540,14 +533,14 @@ fn decide_tag(
|
||||
untagged: BoolAttr,
|
||||
internal_tag: Attr<String>,
|
||||
content: Attr<String>,
|
||||
) -> EnumTag {
|
||||
) -> TagType {
|
||||
match (
|
||||
untagged.0.get_with_tokens(),
|
||||
internal_tag.get_with_tokens(),
|
||||
content.get_with_tokens(),
|
||||
) {
|
||||
(None, None, None) => EnumTag::External,
|
||||
(Some(_), None, None) => EnumTag::None,
|
||||
(None, None, None) => TagType::External,
|
||||
(Some(_), None, None) => TagType::None,
|
||||
(None, Some((_, tag)), None) => {
|
||||
// Check that there are no tuple variants.
|
||||
if let syn::Data::Enum(ref data) = item.data {
|
||||
@@ -567,7 +560,7 @@ fn decide_tag(
|
||||
}
|
||||
}
|
||||
}
|
||||
EnumTag::Internal { tag: tag }
|
||||
TagType::Internal { tag: tag }
|
||||
}
|
||||
(Some((untagged_tokens, _)), Some((tag_tokens, _)), None) => {
|
||||
cx.error_spanned_by(
|
||||
@@ -578,14 +571,14 @@ fn decide_tag(
|
||||
tag_tokens,
|
||||
"enum cannot be both untagged and internally tagged",
|
||||
);
|
||||
EnumTag::External // doesn't matter, will error
|
||||
TagType::External // doesn't matter, will error
|
||||
}
|
||||
(None, None, Some((content_tokens, _))) => {
|
||||
cx.error_spanned_by(
|
||||
content_tokens,
|
||||
"#[serde(tag = \"...\", content = \"...\")] must be used together",
|
||||
);
|
||||
EnumTag::External
|
||||
TagType::External
|
||||
}
|
||||
(Some((untagged_tokens, _)), None, Some((content_tokens, _))) => {
|
||||
cx.error_spanned_by(
|
||||
@@ -596,9 +589,9 @@ fn decide_tag(
|
||||
content_tokens,
|
||||
"untagged enum cannot have #[serde(content = \"...\")]",
|
||||
);
|
||||
EnumTag::External
|
||||
TagType::External
|
||||
}
|
||||
(None, Some((_, tag)), Some((_, content))) => EnumTag::Adjacent {
|
||||
(None, Some((_, tag)), Some((_, content))) => TagType::Adjacent {
|
||||
tag: tag,
|
||||
content: content,
|
||||
},
|
||||
@@ -615,7 +608,7 @@ fn decide_tag(
|
||||
content_tokens,
|
||||
"untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
|
||||
);
|
||||
EnumTag::External
|
||||
TagType::External
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user