vertigo_macro/
lib.rs

1#![feature(proc_macro_span)]
2
3#[macro_use]
4extern crate pest_derive;
5#[macro_use]
6extern crate proc_macro_error;
7
8mod bind;
9mod component;
10mod css_parser;
11mod get_target_dir;
12mod html_parser;
13mod include_static;
14mod js_expression;
15mod jsjson;
16mod main_wrap;
17mod store;
18mod trace_tailwind;
19mod utils;
20mod wasm_path;
21
22use proc_macro::TokenStream;
23use quote::quote;
24
25use crate::{
26    bind::{bind_inner, bind_rc_inner, bind_spawn_inner},
27    component::component_inner,
28    css_parser::generate_css_string,
29    html_parser::{dom_element_inner, dom_inner},
30    include_static::include_static_inner,
31    js_expression::js_expression,
32    main_wrap::main_wrap,
33    store::store_inner,
34    trace_tailwind::trace_tailwind,
35};
36
37#[proc_macro]
38#[proc_macro_error]
39pub fn dom(input: TokenStream) -> TokenStream {
40    dom_inner(input).into()
41}
42
43#[proc_macro]
44#[proc_macro_error]
45pub fn dom_element(input: TokenStream) -> TokenStream {
46    dom_element_inner(input).into()
47}
48
49#[proc_macro]
50#[proc_macro_error]
51pub fn dom_debug(input: TokenStream) -> TokenStream {
52    let stream = dom_inner(input);
53    emit_warning!("debug: {:?}", stream);
54    stream.into()
55}
56
57#[proc_macro]
58#[proc_macro_error]
59pub fn css_block(input: TokenStream) -> TokenStream {
60    let (css_str, _, refs) = generate_css_string(input);
61    let result = quote! {{
62        #refs
63        #css_str
64    }};
65    result.into()
66}
67
68#[proc_macro]
69#[proc_macro_error]
70pub fn css(input: TokenStream) -> TokenStream {
71    let (css_str, is_dynamic, refs) = generate_css_string(input);
72
73    let result = if is_dynamic {
74        quote! {{
75            #refs
76            vertigo::Css::string(#css_str)
77        }}
78    } else {
79        quote! {
80            vertigo::Css::str(#css_str)
81        }
82    };
83    result.into()
84}
85
86#[proc_macro_derive(AutoJsJson, attributes(js_json))]
87#[proc_macro_error]
88pub fn auto_js_json(input: TokenStream) -> TokenStream {
89    let Ok(ast) = syn::parse(input) else {
90        emit_call_site_error!("Failed to parse input");
91        return quote! {}.into();
92    };
93
94    match jsjson::impl_js_json_derive(&ast) {
95        Ok(result) => result,
96        Err(message) => {
97            emit_call_site_error!("{}", message);
98            return quote! {}.into();
99        }
100    }
101}
102
103#[proc_macro]
104#[proc_macro_error]
105pub fn tw(input: TokenStream) -> TokenStream {
106    match trace_tailwind(input) {
107        Ok(token_stream) => token_stream,
108        Err(err) => abort_call_site!(err),
109    }
110}
111
112#[proc_macro]
113#[proc_macro_error]
114pub fn include_static(input: TokenStream) -> TokenStream {
115    include_static_inner(input)
116}
117
118#[proc_macro]
119#[proc_macro_error]
120pub fn bind(input: TokenStream) -> TokenStream {
121    convert_to_tokens(bind_inner(input))
122}
123
124#[proc_macro]
125#[proc_macro_error]
126pub fn bind_spawn(input: TokenStream) -> TokenStream {
127    convert_to_tokens(bind_spawn_inner(input))
128}
129
130#[proc_macro]
131#[proc_macro_error]
132pub fn bind_rc(input: TokenStream) -> TokenStream {
133    convert_to_tokens(bind_rc_inner(input))
134}
135
136#[proc_macro_attribute]
137#[proc_macro_error]
138pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream {
139    main_wrap(input)
140}
141
142#[proc_macro_attribute]
143#[proc_macro_error]
144pub fn component(attrs: TokenStream, input: TokenStream) -> TokenStream {
145    component_inner(attrs, input)
146}
147
148#[proc_macro]
149#[proc_macro_error]
150pub fn js_inner(input: TokenStream) -> TokenStream {
151    js_expression(input)
152}
153
154fn convert_to_tokens(input: Option<TokenStream>) -> TokenStream {
155    match input {
156        Some(body) => body,
157        None => quote! {}.into(),
158    }
159}
160
161#[proc_macro_attribute]
162pub fn store(attr: TokenStream, item: TokenStream) -> TokenStream {
163    store_inner(attr.into(), item.into()).into()
164}