mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 22:52:22 +00:00
Generate everything strum does myself (no duplicate prop names)
This commit is contained in:
@@ -22,7 +22,7 @@ pub struct VariantAttrs {
|
||||
#[darling(attributes(xml))]
|
||||
pub struct EnumAttrs {
|
||||
pub untagged: Flag,
|
||||
pub unit_variants_name: Option<String>,
|
||||
pub unit_variants_ident: Option<syn::Ident>,
|
||||
}
|
||||
|
||||
#[derive(Default, FromDeriveInput, Clone)]
|
||||
|
||||
@@ -2,7 +2,6 @@ use super::{attrs::EnumAttrs, Variant};
|
||||
use crate::attrs::VariantAttrs;
|
||||
use core::panic;
|
||||
use darling::{FromDeriveInput, FromVariant};
|
||||
use proc_macro2::Span;
|
||||
use quote::quote;
|
||||
use syn::{DataEnum, DeriveInput};
|
||||
|
||||
@@ -245,11 +244,11 @@ impl Enum {
|
||||
if self.attrs.untagged.is_present() {
|
||||
panic!("EnumUnitVariants not implemented for untagged enums");
|
||||
}
|
||||
let unit_enum_ident = if let Some(name) = &self.attrs.unit_variants_name {
|
||||
syn::Ident::new(name, Span::call_site())
|
||||
} else {
|
||||
panic!("unit_variants_name not set");
|
||||
};
|
||||
let unit_enum_ident = self
|
||||
.attrs
|
||||
.unit_variants_ident
|
||||
.as_ref()
|
||||
.expect("unit_variants_ident no set");
|
||||
|
||||
let tagged_variants: Vec<_> = self
|
||||
.variants
|
||||
@@ -287,8 +286,15 @@ impl Enum {
|
||||
quote! { #ident::#variant_ident { .. } => #unit_enum_ident::#variant_ident }
|
||||
});
|
||||
|
||||
let str_to_unit_branches = tagged_variants.iter().map(|variant| {
|
||||
let variant_ident = &variant.variant.ident;
|
||||
let b_xml_name = variant.xml_name().value();
|
||||
let xml_name = String::from_utf8_lossy(&b_xml_name);
|
||||
quote! { #xml_name => Ok(#unit_enum_ident::#variant_ident) }
|
||||
});
|
||||
|
||||
quote! {
|
||||
enum #unit_enum_ident {
|
||||
pub enum #unit_enum_ident {
|
||||
#(#variant_idents),*
|
||||
}
|
||||
|
||||
@@ -307,6 +313,17 @@ impl Enum {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::str::FromStr for #unit_enum_ident {
|
||||
type Err = ::rustical_xml::FromStrError;
|
||||
|
||||
fn from_str(val: &str) -> Result<Self, Self::Err> {
|
||||
match val {
|
||||
#(#str_to_unit_branches),*,
|
||||
_ => Err(::rustical_xml::FromStrError)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ pub trait XmlRootTag {
|
||||
fn root_ns_prefixes() -> HashMap<Namespace<'static>, &'static [u8]>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FromStrError;
|
||||
|
||||
pub trait EnumVariants {
|
||||
const TAGGED_VARIANTS: &'static [(Option<Namespace<'static>>, &'static str)];
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use quick_xml::name::Namespace;
|
||||
use rustical_xml::EnumVariants;
|
||||
use xml_derive::EnumUnitVariants;
|
||||
@@ -16,7 +18,7 @@ enum ExtensionProp {
|
||||
}
|
||||
|
||||
#[derive(EnumVariants, EnumUnitVariants)]
|
||||
#[xml(unit_variants_name = "CalendarPropName")]
|
||||
#[xml(unit_variants_ident = "CalendarPropName")]
|
||||
enum CalendarProp {
|
||||
// WebDAV (RFC 2518)
|
||||
#[xml(ns = "NS_DAV")]
|
||||
@@ -73,4 +75,7 @@ fn test_enum_unit_variants() {
|
||||
let propname: CalendarPropName = CalendarProp::Displayname(None).into();
|
||||
let displayname: (Option<Namespace>, &str) = propname.into();
|
||||
assert_eq!(displayname, (Some(NS_DAV), "displayname"));
|
||||
|
||||
let propname: CalendarPropName = FromStr::from_str("displayname").unwrap();
|
||||
assert_eq!(displayname, (Some(NS_DAV), "displayname"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user