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 trace_tailwind;
18mod utils;
19mod wasm_path;
20
21use proc_macro::{Span, TokenStream};
22use quote::quote;
23
24use crate::{
25    bind::{bind_inner, bind_rc_inner, bind_spawn_inner},
26    component::component_inner,
27    css_parser::generate_css_string,
28    html_parser::{dom_element_inner, dom_inner},
29    include_static::include_static_inner,
30    js_expression::js_expression,
31    main_wrap::main_wrap,
32    trace_tailwind::trace_tailwind,
33};
34
35#[proc_macro]
36#[proc_macro_error]
37pub fn dom(input: TokenStream) -> TokenStream {
38    dom_inner(input)
39}
40
41#[proc_macro]
42#[proc_macro_error]
43pub fn dom_element(input: TokenStream) -> TokenStream {
44    dom_element_inner(input)
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
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 ast = syn::parse(input).unwrap();
88
89    match jsjson::impl_js_json_derive(&ast) {
90        Ok(result) => result,
91        Err(message) => {
92            emit_error!(Span::call_site(), "{}", message);
93            let empty = "";
94            quote! { #empty }.into()
95        }
96    }
97}
98
99#[proc_macro]
100#[proc_macro_error]
101pub fn tw(input: TokenStream) -> TokenStream {
102    trace_tailwind(input)
103}
104
105#[proc_macro]
106#[proc_macro_error]
107pub fn include_static(input: TokenStream) -> TokenStream {
108    include_static_inner(input)
109}
110
111#[proc_macro]
112#[proc_macro_error]
113pub fn bind(input: TokenStream) -> TokenStream {
114    convert_to_tokens(bind_inner(input))
115}
116
117#[proc_macro]
118#[proc_macro_error]
119pub fn bind_spawn(input: TokenStream) -> TokenStream {
120    convert_to_tokens(bind_spawn_inner(input))
121}
122
123#[proc_macro]
124#[proc_macro_error]
125pub fn bind_rc(input: TokenStream) -> TokenStream {
126    convert_to_tokens(bind_rc_inner(input))
127}
128
129#[proc_macro_attribute]
130#[proc_macro_error]
131pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream {
132    main_wrap(input)
133}
134
135#[proc_macro_attribute]
136#[proc_macro_error]
137pub fn component(attrs: TokenStream, input: TokenStream) -> TokenStream {
138    component_inner(attrs, input)
139}
140
141#[proc_macro]
142#[proc_macro_error]
143pub fn js_inner(input: TokenStream) -> TokenStream {
144    js_expression(input)
145}
146
147fn convert_to_tokens(input: Result<TokenStream, String>) -> TokenStream {
148    match input {
149        Ok(body) => body,
150        Err(message) => {
151            emit_error!(Span::call_site(), "{}", message);
152            let empty = "";
153            quote! { #empty }.into()
154        }
155    }
156}