resuma_macros/lib.rs
1//! Resuma procedural macros.
2//!
3//! Re-exported by the [`resuma`](https://docs.rs/resuma) crate. Typical surface:
4//!
5//! | Macro | Role |
6//! |-------|------|
7//! | [`view!`] | JSX-like templates → [`View`](https://docs.rs/resuma/latest/resuma/enum.View.html) |
8//! | [`#[component]`](component) | Resumable component + props builder (lazy handler boundary) |
9//! | [`#[server]`](server) | Async RPC at `POST /_resuma/action/:name` |
10//! | [`#[data]`](data) | Concise typed DTO/model helper |
11//! | [`computed!`](computed) | Client-replayable derived signal (rs2js) |
12//! | [`effect!`](effect) | Client-replayable side effect (rs2js) |
13//! | [`debounce!`](debounce) | Debounced client reaction |
14//! | [`#[island]`](island) | Optional heavy lazy boundary (`load = "visible"`) |
15//! | [`js!`](js) | Raw JavaScript handler escape hatch |
16
17mod extract_codegen;
18mod component_macro;
19mod computed_macro;
20mod data_macro;
21mod debounce_macro;
22mod effect_macro;
23mod island_macro;
24mod js_macro;
25mod layout_macro;
26mod load_macro;
27mod middleware_macro;
28mod rs2js;
29mod server_macro;
30mod store_macro;
31mod submit_macro;
32mod view_macro;
33
34use proc_macro::TokenStream;
35
36/// `view!` — JSX-like template macro.
37#[proc_macro]
38pub fn view(input: TokenStream) -> TokenStream {
39 view_macro::expand(input.into()).into()
40}
41
42/// `#[component]` — resumable component with generated props builder.
43///
44/// Wraps output in a lazy handler boundary; event handlers register under
45/// `/_resuma/handler/{ComponentName}.js`. For heavy optional lazy bundles, see [`island`].
46#[proc_macro_attribute]
47pub fn component(args: TokenStream, input: TokenStream) -> TokenStream {
48 component_macro::expand(args.into(), input.into()).into()
49}
50
51/// `#[server]` — exposes an async fn as a server action.
52#[proc_macro_attribute]
53pub fn server(args: TokenStream, input: TokenStream) -> TokenStream {
54 server_macro::expand(args.into(), input.into()).into()
55}
56
57/// `#[data]` — concise DTO/model helper for Resuma data structs and enums.
58#[proc_macro_attribute]
59pub fn data(args: TokenStream, input: TokenStream) -> TokenStream {
60 data_macro::expand(args.into(), input.into()).into()
61}
62
63/// `#[island]` — optional interactive boundary for heavy or visibility-gated JS.
64///
65/// Most UI only needs [`component`]. Use islands for large client bundles,
66/// `#[island(load = "visible")]`, or dev HMR refresh via `GET /_resuma/island/:instance`.
67#[proc_macro_attribute]
68pub fn island(args: TokenStream, input: TokenStream) -> TokenStream {
69 island_macro::expand(args.into(), input.into()).into()
70}
71
72/// `#[load]` — Resuma Flow server data loader.
73#[proc_macro_attribute]
74pub fn load(args: TokenStream, input: TokenStream) -> TokenStream {
75 load_macro::expand(args.into(), input.into()).into()
76}
77
78/// `#[submit]` — Resuma Flow form submission handler.
79#[proc_macro_attribute]
80pub fn submit(args: TokenStream, input: TokenStream) -> TokenStream {
81 submit_macro::expand(args.into(), input.into()).into()
82}
83
84/// `#[layout]` — Resuma Flow layout wrapper.
85#[proc_macro_attribute]
86pub fn layout(args: TokenStream, input: TokenStream) -> TokenStream {
87 layout_macro::expand(args.into(), input.into()).into()
88}
89
90/// `#[middleware]` — Resuma Flow request middleware.
91#[proc_macro_attribute]
92pub fn middleware(args: TokenStream, input: TokenStream) -> TokenStream {
93 middleware_macro::expand(args.into(), input.into()).into()
94}
95
96/// `js!` — raw JavaScript escape hatch for event handlers.
97#[proc_macro]
98pub fn js(input: TokenStream) -> TokenStream {
99 js_macro::expand(input.into()).into()
100}
101
102/// `computed!([deps…], move || …)` — derived signal with client replay (rs2js-translated).
103///
104/// Runs during SSR and replays in the browser when dependencies change.
105/// For SSR-only derived state, use [`use_computed`](https://docs.rs/resuma/latest/resuma/fn.use_computed.html) instead.
106#[proc_macro]
107pub fn computed(input: TokenStream) -> TokenStream {
108 computed_macro::expand(input.into()).into()
109}
110
111/// `effect!([signals…], move || { … })` — client-replayable side effect (rs2js).
112#[proc_macro]
113pub fn effect(input: TokenStream) -> TokenStream {
114 effect_macro::expand(input.into()).into()
115}
116
117#[proc_macro_derive(Store)]
118pub fn derive_store(input: TokenStream) -> TokenStream {
119 store_macro::derive(input)
120}
121
122/// `debounce!([deps…], ms, move || …)` — debounced client reaction (rs2js-translated).
123///
124/// ```ignore
125/// debounce!([search], 300, move || { /* runs after search settles */ });
126/// ```
127#[proc_macro]
128pub fn debounce(input: TokenStream) -> TokenStream {
129 debounce_macro::expand(input.into()).into()
130}