Generalize scalar to enum mode

This commit is contained in:
Dirkjan Ochtman 2022-11-22 20:39:11 -08:00
parent 23abf75725
commit a4f35e5daa
3 changed files with 22 additions and 37 deletions

View File

@ -11,13 +11,12 @@ pub(crate) fn from_xml(input: &syn::DeriveInput) -> TokenStream {
}; };
match &input.data { match &input.data {
syn::Data::Struct(_) if meta.scalar => { syn::Data::Struct(_) if meta.mode.is_some() => {
syn::Error::new(input.span(), "scalar structs are unsupported!").to_compile_error() syn::Error::new(input.span(), "no enum mode allowed on struct type").to_compile_error()
} }
syn::Data::Struct(ref data) => deserialize_struct(input, data, meta), syn::Data::Struct(ref data) => deserialize_struct(input, data, meta),
syn::Data::Enum(_) if !meta.scalar => { syn::Data::Enum(_) if meta.mode.is_none() => {
syn::Error::new(input.span(), "non-scalar enums are currently unsupported!") syn::Error::new(input.span(), "missing enum mode").to_compile_error()
.to_compile_error()
} }
syn::Data::Enum(ref data) => deserialize_enum(input, data, meta), syn::Data::Enum(ref data) => deserialize_enum(input, data, meta),
_ => todo!(), _ => todo!(),

View File

@ -33,7 +33,7 @@ struct ContainerMeta<'input> {
ns: NamespaceMeta, ns: NamespaceMeta,
rename: Option<Literal>, rename: Option<Literal>,
rename_all: RenameRule, rename_all: RenameRule,
scalar: bool, mode: Option<Mode>,
} }
impl<'input> ContainerMeta<'input> { impl<'input> ContainerMeta<'input> {
@ -41,7 +41,7 @@ impl<'input> ContainerMeta<'input> {
let mut ns = NamespaceMeta::default(); let mut ns = NamespaceMeta::default();
let mut rename = Default::default(); let mut rename = Default::default();
let mut rename_all = Default::default(); let mut rename_all = Default::default();
let mut scalar = Default::default(); let mut mode = None;
for (item, span) in meta_items(&input.attrs) { for (item, span) in meta_items(&input.attrs) {
match item { match item {
@ -59,7 +59,10 @@ impl<'input> ContainerMeta<'input> {
Err(err) => return Err(syn::Error::new(span, err)), Err(err) => return Err(syn::Error::new(span, err)),
}; };
} }
MetaItem::Scalar => scalar = true, MetaItem::Scalar => match mode {
None => mode = Some(Mode::Scalar),
Some(_) => return Err(syn::Error::new(span, "cannot have two enum modes")),
},
} }
} }
@ -68,7 +71,7 @@ impl<'input> ContainerMeta<'input> {
ns, ns,
rename, rename,
rename_all, rename_all,
scalar, mode,
}) })
} }
@ -133,10 +136,7 @@ impl FieldMeta {
)) ))
} }
MetaItem::Scalar => { MetaItem::Scalar => {
return Err(syn::Error::new( return Err(syn::Error::new(span, "invalid attribute for struct field"));
span,
"attribute 'scalar' is invalid for struct fields",
))
} }
} }
} }
@ -166,28 +166,10 @@ impl VariantMeta {
for (item, span) in meta_items(&input.attrs) { for (item, span) in meta_items(&input.attrs) {
match item { match item {
MetaItem::Rename(lit) => rename = Some(lit.to_token_stream()), MetaItem::Rename(lit) => rename = Some(lit.to_token_stream()),
MetaItem::Attribute => { _ => {
return Err(syn::Error::new( return Err(syn::Error::new(
span, span,
"attribute 'attribute' is invalid for enum variants", "only 'rename' attribute is permitted on enum variants",
))
}
MetaItem::Ns(_ns) => {
return Err(syn::Error::new(
span,
"attribute 'ns' is invalid for enum variants",
))
}
MetaItem::RenameAll(_) => {
return Err(syn::Error::new(
span,
"attribute 'rename_all' invalid in field xml attribute",
))
}
MetaItem::Scalar => {
return Err(syn::Error::new(
span,
"attribute 'scalar' is invalid for enum variants",
)) ))
} }
} }
@ -715,6 +697,10 @@ fn discard_path_lifetimes(path: &mut syn::TypePath) {
} }
} }
enum Mode {
Scalar,
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use syn::parse_quote; use syn::parse_quote;

View File

@ -13,12 +13,12 @@ pub fn to_xml(input: &syn::DeriveInput) -> proc_macro2::TokenStream {
}; };
match &input.data { match &input.data {
syn::Data::Struct(_) if meta.scalar => { syn::Data::Struct(_) if meta.mode.is_some() => {
syn::Error::new(input.span(), "scalar structs are unsupported!").to_compile_error() syn::Error::new(input.span(), "enum mode not allowed on struct type").to_compile_error()
} }
syn::Data::Struct(ref data) => serialize_struct(input, data, meta), syn::Data::Struct(ref data) => serialize_struct(input, data, meta),
syn::Data::Enum(_) if !meta.scalar => { syn::Data::Enum(_) if meta.mode.is_none() => {
syn::Error::new(input.span(), "non-scalar enums are currently unsupported!") syn::Error::new(input.span(), "missing enum mode")
.to_compile_error() .to_compile_error()
} }
syn::Data::Enum(ref data) => serialize_enum(input, data, meta), syn::Data::Enum(ref data) => serialize_enum(input, data, meta),