1mod style;
2
3use style::ParsedVariants;
4
5use proc_macro::TokenStream;
6use quote::quote;
7use syn::{parse_macro_input, Data, DeriveInput};
8
9#[allow(clippy::missing_panics_doc)]
10#[proc_macro_derive(StyleParser, attributes(property, parser, style_class))]
11pub fn derive_style_parser(input: TokenStream) -> TokenStream {
12 let input = parse_macro_input!(input as DeriveInput);
13 let name = input.ident;
14 let generics = input.generics;
15 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
16 let Data::Enum(e) = input.data else {
17 panic!("StyleParser can be only derived to enum")
18 };
19 let ParsedVariants {
20 idents,
21 properties,
22 parsers,
23 style_classes,
24 } = ParsedVariants::from(&e.variants);
25
26 quote! {
27 impl #impl_generics #name #ty_generics #where_clause {
28 pub fn from_cow((key, value): (&std::borrow::Cow<'_, str>, &std::borrow::Cow<'_, str>)) -> Option<Self> {
29 match key.as_ref() {
30 #( #properties => Some(Self::#idents(#parsers(value)?)), )*
31 unknown => None,
32 }
33 }
34
35 fn apply_transition(s: floem::style::Style, key: &str, t: floem::style::Transition) -> floem::style::Style {
36 match key {
37 #( #properties => s.transition(#style_classes, t), )*
38 invalid => {
39 log::error!("Invalid transition key '{invalid}'");
40 s
41 },
42 }
43 }
44 }
45 }
46 .into()
47}