terrazzo_macro/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use quote::format_ident;
4
5mod arguments;
6mod html;
7use server_fn_macro::server_macro_impl;
8mod template;
9
10#[proc_macro_attribute]
11pub fn html(
12    attr: proc_macro::TokenStream,
13    item: proc_macro::TokenStream,
14) -> proc_macro::TokenStream {
15    self::html::html(attr.into(), item.into())
16        .unwrap_or_else(syn::Error::into_compile_error)
17        .into()
18}
19
20#[proc_macro_attribute]
21pub fn template(
22    attr: proc_macro::TokenStream,
23    item: proc_macro::TokenStream,
24) -> proc_macro::TokenStream {
25    self::template::template(attr.into(), item.into())
26        .unwrap_or_else(syn::Error::into_compile_error)
27        .into()
28}
29
30#[proc_macro_attribute]
31pub fn server(
32    args: proc_macro::TokenStream,
33    s: proc_macro::TokenStream,
34) -> proc_macro::TokenStream {
35    match server_macro_impl(
36        args.into(),
37        s.into(),
38        Some(syn::parse_quote!(::server_fn)),
39        "/api/fn",
40        None,
41        None,
42    ) {
43        Err(e) => e.to_compile_error().into(),
44        Ok(s) => s.into(),
45    }
46}
47
48fn item_to_string(item: &syn::Item) -> String {
49    prettyplease::unparse(&syn::File {
50        shebang: None,
51        attrs: vec![],
52        items: vec![item.clone()],
53    })
54}
55
56fn is_path(path: &syn::Path, expected: &'static str) -> bool {
57    let syn::Path {
58        leading_colon: None,
59        segments,
60    } = path
61    else {
62        return false;
63    };
64    let Some(segment) = segments.last() else {
65        return false;
66    };
67    if segments.len() != 1 {
68        return false;
69    }
70    let syn::PathArguments::None = segment.arguments else {
71        return false;
72    };
73    return segment.ident == format_ident!("{}", expected);
74}