Skip to main content

omnifs_sdk_macros/
lib.rs

1//! Proc macros for the omnifs provider SDK.
2//!
3//! `#[provider]` processes a provider lifecycle impl block and stitches
4//! together handler modules declared in `#[provider(mounts(...))]`.
5//!
6//! Inside `#[handlers] impl T { ... }`, `#[dir]`, `#[file]`,
7//! `#[treeref]`, `#[bind]`, and reserved `#[mutate]` annotate methods
8//! that become path handlers. `#[bind]` dispatches into a typed subtree
9//! defined by `#[subtree] impl B { ... }`.
10
11use proc_macro::TokenStream;
12use syn::{Item, ItemFn, ItemImpl, parse_macro_input};
13
14const HANDLERS_ATTRIBUTE_SCOPE_ERROR: &str =
15    "must be used inside an `impl` block annotated with #[omnifs_sdk::handlers]";
16
17mod config_macro;
18mod handler_macro;
19mod provider_macro;
20mod subtree_macro;
21
22/// Attribute macro for omnifs provider impl blocks.
23#[proc_macro_attribute]
24pub fn provider(attr: TokenStream, item: TokenStream) -> TokenStream {
25    let args = parse_macro_input!(attr as provider_macro::ProviderArgs);
26    let input = parse_macro_input!(item as ItemImpl);
27    match provider_macro::provider_impl(&args, input) {
28        Ok(tokens) => tokens.into(),
29        Err(error) => error.to_compile_error().into(),
30    }
31}
32
33#[proc_macro_attribute]
34pub fn config(_attr: TokenStream, item: TokenStream) -> TokenStream {
35    let input = parse_macro_input!(item as Item);
36    match config_macro::config_item_impl(input) {
37        Ok(tokens) => tokens.into(),
38        Err(error) => error.to_compile_error().into(),
39    }
40}
41
42#[allow(non_snake_case)]
43#[proc_macro_attribute]
44pub fn Config(attr: TokenStream, item: TokenStream) -> TokenStream {
45    config(attr, item)
46}
47
48fn handlers_attr_scope_error() -> TokenStream {
49    syn::Error::new(
50        proc_macro2::Span::call_site(),
51        HANDLERS_ATTRIBUTE_SCOPE_ERROR,
52    )
53    .to_compile_error()
54    .into()
55}
56
57#[proc_macro_attribute]
58pub fn dir(_attr: TokenStream, item: TokenStream) -> TokenStream {
59    let _func = parse_macro_input!(item as ItemFn);
60    handlers_attr_scope_error()
61}
62
63#[proc_macro_attribute]
64pub fn file(_attr: TokenStream, item: TokenStream) -> TokenStream {
65    let _func = parse_macro_input!(item as ItemFn);
66    handlers_attr_scope_error()
67}
68
69#[proc_macro_attribute]
70pub fn treeref(_attr: TokenStream, item: TokenStream) -> TokenStream {
71    let _func = parse_macro_input!(item as ItemFn);
72    handlers_attr_scope_error()
73}
74
75#[proc_macro_attribute]
76pub fn bind(_attr: TokenStream, item: TokenStream) -> TokenStream {
77    let _func = parse_macro_input!(item as ItemFn);
78    handlers_attr_scope_error()
79}
80
81#[proc_macro_attribute]
82pub fn handlers(attr: TokenStream, item: TokenStream) -> TokenStream {
83    let args = parse_macro_input!(attr as handler_macro::HandlersArgs);
84    let input = parse_macro_input!(item as ItemImpl);
85    match handler_macro::expand_handlers(&args, input) {
86        Ok(tokens) => tokens.into(),
87        Err(error) => error.to_compile_error().into(),
88    }
89}
90
91#[proc_macro_attribute]
92pub fn subtree(attr: TokenStream, item: TokenStream) -> TokenStream {
93    let args = parse_macro_input!(attr as subtree_macro::SubtreeArgs);
94    let input = parse_macro_input!(item as ItemImpl);
95    match subtree_macro::expand_subtree(&args, input) {
96        Ok(tokens) => tokens.into(),
97        Err(error) => error.to_compile_error().into(),
98    }
99}
100
101#[proc_macro_attribute]
102pub fn mutate(attr: TokenStream, item: TokenStream) -> TokenStream {
103    let func = parse_macro_input!(item as ItemFn);
104    match handler_macro::expand_handler(
105        handler_macro::HandlerKind::Mutate,
106        parse_macro_input!(attr as handler_macro::HandlerArgs),
107        func,
108    ) {
109        Ok(tokens) => tokens.into(),
110        Err(error) => error.to_compile_error().into(),
111    }
112}
113
114#[proc_macro]
115pub fn mounts(item: TokenStream) -> TokenStream {
116    let _ = item;
117    syn::Error::new(
118        proc_macro2::Span::call_site(),
119        "mounts! has been removed; declare free-function handlers with #[dir]/#[file]/#[subtree] and mount modules from #[omnifs_sdk::provider]",
120    )
121    .to_compile_error()
122    .into()
123}