crux_macros/lib.rs
1#![deny(clippy::pedantic)]
2
3mod capability;
4mod effect;
5mod export;
6
7use capability::capability_impl;
8use export::export_impl;
9use proc_macro::TokenStream;
10use proc_macro_error::proc_macro_error;
11use syn::{Ident, ItemEnum, parse_macro_input};
12
13/// Generates an effect type matching the enum definition provided,
14/// whilst supplying all the necessary decorations and additional trait implementations.
15///
16/// Use `typegen` as an argument if you want to opt in to the built-in foreign type generation.
17///
18/// e.g.
19/// ```rust
20/// # use crux_core::{render::RenderOperation};
21/// # use crux_core::macros::effect;
22/// # use crux_http::protocol::HttpRequest;
23/// # #[derive(Default)]
24/// # struct MyApp;
25/// # pub enum MyEvent {None}
26/// # impl crux_core::App for MyApp {
27/// # type Event = MyEvent;
28/// # type Model = ();
29/// # type ViewModel = ();
30/// # type Effect = MyEffect;
31/// # fn update(
32/// # &self,
33/// # _event: Self::Event,
34/// # _model: &mut Self::Model,
35/// # ) -> crux_core::Command<MyEffect, MyEvent> {
36/// # unimplemented!()
37/// # }
38/// # fn view(&self, _model: &Self::Model) -> Self::ViewModel {
39/// # unimplemented!()
40/// # }
41/// # }
42/// #[effect(typegen)]
43/// pub enum MyEffect {
44/// Render(RenderOperation),
45/// Http(HttpRequest),
46/// }
47/// ```
48#[proc_macro_attribute]
49pub fn effect(args: TokenStream, input: TokenStream) -> TokenStream {
50 let args = parse_macro_input!(args as Option<Ident>);
51 let input = parse_macro_input!(input as ItemEnum);
52 effect::macro_impl::effect_impl(args, input).into()
53}
54
55#[proc_macro_derive(Export)]
56#[proc_macro_error]
57pub fn export(input: TokenStream) -> TokenStream {
58 export_impl(&parse_macro_input!(input)).into()
59}
60
61/// Deprecated: use the `effect` attribute macro instead.
62#[proc_macro_derive(Capability)]
63#[proc_macro_error]
64pub fn capability(input: TokenStream) -> TokenStream {
65 capability_impl(&parse_macro_input!(input)).into()
66}
67
68#[cfg(test)]
69fn pretty_print(ts: &proc_macro2::TokenStream) -> String {
70 let file = syn::parse_file(&ts.to_string()).unwrap();
71 prettyplease::unparse(&file)
72}