floem_css_macros/
lib.rs

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}