Skip to main content

orbital_macros/
lib.rs

1//! Proc macros for Orbital design-system documentation and routing helpers.
2
3use proc_macro::TokenStream;
4
5mod component_doc;
6mod routes;
7mod routes_extract;
8mod write_css_vars;
9
10use quote::quote;
11use syn::parse::{Parse, ParseStream};
12use syn::{parse_macro_input, Token};
13
14/// Extract documentation and props from a component for preview tooling.
15#[proc_macro_attribute]
16pub fn component_doc(attr: TokenStream, input: TokenStream) -> TokenStream {
17    component_doc::expand_component_doc(attr, input)
18}
19
20struct RouteComponents {
21    components: Vec<syn::Ident>,
22}
23
24impl Parse for RouteComponents {
25    fn parse(input: ParseStream) -> syn::Result<Self> {
26        let mut components = Vec::new();
27        while !input.is_empty() {
28            let ident: syn::Ident = input.parse()?;
29            components.push(ident);
30            if input.peek(Token![,]) {
31                input.parse::<Token![,]>()?;
32            } else {
33                break;
34            }
35        }
36        Ok(RouteComponents { components })
37    }
38}
39
40/// Include multiple route components in a Routes view.
41#[proc_macro]
42pub fn orbital_routes(input: TokenStream) -> TokenStream {
43    let RouteComponents { components } = parse_macro_input!(input);
44    let route_components = components.iter().map(|ident| {
45        quote! { <#ident /> }
46    });
47    quote! { #(#route_components)* }.into()
48}
49
50/// Extract typed path constants from a route component's `view!` body.
51#[proc_macro_attribute]
52pub fn orbital_routes_extract(attr: TokenStream, input: TokenStream) -> TokenStream {
53    routes_extract::expand_routes(attr, input)
54}
55
56/// Derives `write_css_vars` for theme token structs (snake_case field → `--camelCase` CSS var).
57#[proc_macro_derive(WriteCSSVars)]
58pub fn write_css_vars(input: TokenStream) -> TokenStream {
59    let input = syn::parse_macro_input!(input as syn::DeriveInput);
60    write_css_vars::expand_write_css_vars(input).into()
61}