Skip to main content

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}