diff options
| author | Jonas Maier <jonas@x77.dev> | 2026-05-23 14:48:51 +0200 |
|---|---|---|
| committer | Jonas Maier <jonas@x77.dev> | 2026-05-23 14:48:51 +0200 |
| commit | e4c0fc7beab2a6dd53210263a857f2b3ec29b604 (patch) | |
| tree | 47137f101e5caaa93273cb03eeea92e0616537ca /pish_derive | |
| parent | ba9414b17a107bdb30fe462aa2d42f6e91b3ad74 (diff) | |
| download | pish-e4c0fc7beab2a6dd53210263a857f2b3ec29b604.tar.gz | |
customizable syntax highlighting
Diffstat (limited to 'pish_derive')
| -rw-r--r-- | pish_derive/src/lib.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/pish_derive/src/lib.rs b/pish_derive/src/lib.rs index 3a296fc..3a2fddc 100644 --- a/pish_derive/src/lib.rs +++ b/pish_derive/src/lib.rs @@ -94,3 +94,67 @@ pub fn derive_cli(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } + +// AI-generated +#[proc_macro_derive(Variants)] +pub fn derive_variants(item: TokenStream) -> TokenStream { + let original = item.to_string(); + + // ---- extract enum name ---- + let mut tokens = original.split_whitespace(); + + let mut enum_name = None; + while let Some(t) = tokens.next() { + if t == "enum" { + enum_name = tokens.next().map(|s| s.trim_matches('{').to_string()); + break; + } + } + + let enum_name = match enum_name { + Some(n) => n, + None => return r#"compile_error!("expected enum")"#.parse().unwrap(), + }; + + // ---- extract body between braces ---- + let start = original.find('{').expect("missing '{'"); + let end = original.rfind('}').expect("missing '}'"); + let body = &original[start + 1..end]; + + // ---- parse variants ---- + let mut variants = Vec::new(); + + for part in body.split(',') { + let v = part.trim(); + if v.is_empty() { + continue; + } + + // take first token as variant name + let name = v.split_whitespace().next().unwrap_or("").trim(); + + if name.is_empty() { + continue; + } + + // reject non-unit variants + if v.contains('(') || v.contains('{') || v.contains('=') { + return r#"compile_error!("only unit variants supported")"#.parse().unwrap(); + } + + variants.push(format!("{}::{}", enum_name, name)); + } + + let variants_joined = variants.join(", "); + + let expanded = format!( + " +impl crate::variants::Variants for {enum_name} {{ + const VARIANTS: &'static [Self] = &[ + {variants_joined} + ]; +}}" + ); + + expanded.parse().unwrap() +} |
