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 api_access;
9mod bind;
10mod component;
11mod css_parser;
12mod html_parser;
13mod include_static;
14mod jsjson;
15mod main_wrap;
16mod wasm_path;
17
18use proc_macro::{Span, TokenStream};
19use quote::quote;
20
21use crate::{
22    api_access::api_access_inner,
23    bind::{bind_inner, bind_rc_inner, bind_spawn_inner},
24    component::component_inner,
25    css_parser::generate_css_string,
26    html_parser::{dom_element_inner, dom_inner},
27    include_static::include_static_inner,
28    main_wrap::main_wrap,
29};
30
31#[proc_macro]
32#[proc_macro_error]
33pub fn dom(input: TokenStream) -> TokenStream {
34    dom_inner(input)
35}
36
37#[proc_macro]
38#[proc_macro_error]
39pub fn dom_element(input: TokenStream) -> TokenStream {
40    dom_element_inner(input)
41}
42
43#[proc_macro]
44#[proc_macro_error]
45pub fn dom_debug(input: TokenStream) -> TokenStream {
46    let stream = dom_inner(input);
47    emit_warning!("debug: {:?}", stream);
48    stream
49}
50
51#[proc_macro]
52#[proc_macro_error]
53pub fn css_block(input: TokenStream) -> TokenStream {
54    let (css_str, _, refs) = generate_css_string(input);
55    let result = quote! {{
56        #refs
57        #css_str
58    }};
59    result.into()
60}
61
62#[proc_macro]
63#[proc_macro_error]
64pub fn css(input: TokenStream) -> TokenStream {
65    let (css_str, is_dynamic, refs) = generate_css_string(input);
66
67    let result = if is_dynamic {
68        quote! {{
69            #refs
70            vertigo::Css::string(#css_str)
71        }}
72    } else {
73        quote! {
74            vertigo::Css::str(#css_str)
75        }
76    };
77    result.into()
78}
79
80#[proc_macro_derive(AutoJsJson, attributes(js_json))]
81#[proc_macro_error]
82pub fn auto_js_json(input: TokenStream) -> TokenStream {
83    let ast = syn::parse(input).unwrap();
84
85    match jsjson::impl_js_json_derive(&ast) {
86        Ok(result) => result,
87        Err(message) => {
88            emit_error!(Span::call_site(), "{}", message);
89            let empty = "";
90            quote! { #empty }.into()
91        }
92    }
93}
94
95#[proc_macro]
96#[proc_macro_error]
97pub fn include_static(input: TokenStream) -> TokenStream {
98    include_static_inner(input)
99}
100
101#[proc_macro]
102#[proc_macro_error]
103pub fn bind(input: TokenStream) -> TokenStream {
104    convert_to_tokens(bind_inner(input))
105}
106
107#[proc_macro]
108#[proc_macro_error]
109pub fn bind_spawn(input: TokenStream) -> TokenStream {
110    convert_to_tokens(bind_spawn_inner(input))
111}
112
113#[proc_macro]
114#[proc_macro_error]
115pub fn bind_rc(input: TokenStream) -> TokenStream {
116    convert_to_tokens(bind_rc_inner(input))
117}
118
119#[proc_macro_attribute]
120pub fn main(_attr: TokenStream, input: TokenStream) -> TokenStream {
121    main_wrap(input)
122}
123
124#[proc_macro_attribute]
125#[proc_macro_error]
126pub fn component(_attrs: TokenStream, input: TokenStream) -> TokenStream {
127    component_inner(input)
128}
129
130#[proc_macro]
131#[proc_macro_error]
132pub fn window(input: TokenStream) -> TokenStream {
133    api_access_inner("window", input)
134}
135
136#[proc_macro]
137#[proc_macro_error]
138pub fn document(input: TokenStream) -> TokenStream {
139    api_access_inner("document", input)
140}
141
142fn convert_to_tokens(input: Result<TokenStream, String>) -> TokenStream {
143    match input {
144        Ok(body) => body,
145        Err(message) => {
146            emit_error!(Span::call_site(), "{}", message);
147            let empty = "";
148            quote! { #empty }.into()
149        }
150    }
151}