Skip to main content

formualizer_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{Path, Token, parse::Parser, punctuated::Punctuated};
4
5/// Macro to generate the caps() method and validate that required methods are implemented
6/// Usage:
7/// ```ignore
8/// use formualizer_eval::function::Function;
9/// pub struct SumFn;
10/// impl Function for SumFn {
11///     func_caps!(PURE, REDUCTION, NUMERIC_ONLY, STREAM_OK);
12///     
13///     fn name(&self) -> &'static str { "SUM" }
14///     // ... rest of implementation
15/// }
16/// ```
17#[proc_macro]
18pub fn func_caps(input: TokenStream) -> TokenStream {
19    let parser = Punctuated::<Path, Token![,]>::parse_terminated;
20    let paths = parser
21        .parse(input)
22        .expect("Failed to parse capability flags");
23
24    let cap_tokens: Vec<_> = paths
25        .iter()
26        .map(|path| {
27            quote! { crate::function::FnCaps::#path }
28        })
29        .collect();
30
31    let caps_expr = if cap_tokens.is_empty() {
32        quote! { crate::function::FnCaps::empty() }
33    } else {
34        let first = &cap_tokens[0];
35        let rest = &cap_tokens[1..];
36
37        rest.iter().fold(quote! { #first }, |acc, token| {
38            quote! { #acc | #token }
39        })
40    };
41
42    let expanded = quote! {
43        fn caps(&self) -> crate::function::FnCaps {
44            #caps_expr
45        }
46    };
47
48    TokenStream::from(expanded)
49}