Skip to main content

vertigo_macro/
lib.rs

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