derive_atom_set/lib.rs
1#![doc = include_str!("../README.md")]
2
3use proc_macro::TokenStream;
4use syn::{DeriveInput, parse_macro_input};
5
6mod atom_set;
7
8/// Derives an efficient `AtomSet` implementation (the trait from the `atom_set` crate) for interned identifiers.
9///
10/// This proc macro automatically generates optimized string-to-enum matching code.
11///
12/// ## Variant Attributes
13///
14/// - `#[default]`: Marks this variant as the empty/fallback value (returns empty string)
15/// - `#[atom("custom")]`: Overrides the default string representation
16///
17/// ## Naming Convention
18///
19/// If `#[atom("")]` is not provided a string is derived from the variant name:
20/// - `Px` → `"px"`
21/// - `FontSize` → `"font-size"`
22/// - `WebkitTransform` → `"webkit-transform"`
23///
24/// # Example
25///
26/// ```rust
27/// use atom_set::AtomSet;
28/// use derive_atom_set::AtomSet as DeriveAtomSet;
29///
30/// #[derive(Debug, Default, Copy, Clone, PartialEq, DeriveAtomSet)]
31/// pub enum MyAtomSet {
32/// #[default]
33/// Unknown, // Must provide an empty default!
34///
35/// // Absolute units
36/// Px, Pt, Pc, In, Cm, Mm, Q,
37///
38/// // Relative units
39/// Em, Ex, Ch, Rem, Lh,
40///
41/// // Viewport units
42/// Vw, Vh, Vi, Vb, Vmin, Vmax,
43///
44/// // Container query units
45/// Cqw, Cqh, Cqi, Cqb, Cqmin, Cqmax,
46///
47/// // Special case
48/// #[atom("%")]
49/// Percent,
50/// }
51///
52/// // Usage:
53/// assert_eq!(MyAtomSet::from_str("px"), MyAtomSet::Px);
54/// assert_eq!(MyAtomSet::from_str("PX"), MyAtomSet::Px); // Case insensitive matches
55/// assert_eq!(MyAtomSet::Px.to_str(), "px");
56/// assert_eq!(MyAtomSet::Percent.to_str(), "%");
57/// assert_eq!(MyAtomSet::from_str("unknown"), MyAtomSet::Unknown);
58/// ```
59#[proc_macro_derive(AtomSet, attributes(default, atom))]
60pub fn derive_atom_set(input: TokenStream) -> TokenStream {
61 let ast = parse_macro_input!(input as DeriveInput);
62 atom_set::generate(proc_macro2::TokenStream::new(), ast).into()
63}