1use proc_macro::TokenStream;
4use syn::{DeriveInput, parse_macro_input};
5
6mod aggregate;
7mod case;
8#[cfg(feature = "children")]
9mod children;
10#[cfg(feature = "config")]
11mod config;
12mod constraints;
13#[cfg(feature = "contracts")]
14mod contracts;
15mod crate_path;
16mod enumeration;
17mod event;
18mod every;
19#[cfg(feature = "factories")]
20mod factory;
21#[cfg(feature = "fixtures")]
22mod fixture;
23mod input;
24#[cfg(feature = "joins")]
25mod joins;
26#[cfg(feature = "retention")]
27mod pruned;
28mod read_model;
29#[cfg(feature = "remote-contracts")]
30mod remote;
31mod sensitive;
32mod serialize;
33mod shape;
34#[cfg(feature = "span")]
35mod span;
36#[cfg(feature = "tasks")]
37mod task;
38mod value;
39
40#[proc_macro_derive(
46 Aggregate,
47 attributes(
48 sofie, owner, aggregate, min, max, length, range, required, unique, expose, mirror,
49 sensitive
50 )
51)]
52pub fn derive_aggregate(item: TokenStream) -> TokenStream {
53 expand(item, aggregate::derive)
54}
55
56#[cfg(feature = "children")]
58#[proc_macro_derive(Child, attributes(sofie, min, max, length, range, required))]
59pub fn derive_child(item: TokenStream) -> TokenStream {
60 expand(item, children::derive)
61}
62
63#[proc_macro_derive(Value, attributes(sofie, sensitive))]
67pub fn derive_value(item: TokenStream) -> TokenStream {
68 expand(item, value::derive)
69}
70
71#[cfg(feature = "config")]
74#[proc_macro_derive(Config, attributes(sofie))]
75pub fn derive_config(item: TokenStream) -> TokenStream {
76 expand(item, config::derive)
77}
78
79#[proc_macro_derive(Enum, attributes(sofie, to, tone))]
81pub fn derive_enum(item: TokenStream) -> TokenStream {
82 expand(item, enumeration::derive)
83}
84
85#[proc_macro_derive(ReadModel, attributes(sofie, read, sensitive))]
89pub fn derive_read_model(item: TokenStream) -> TokenStream {
90 expand(item, read_model::derive)
91}
92
93#[proc_macro_derive(Event, attributes(sofie))]
94pub fn derive_event(item: TokenStream) -> TokenStream {
95 expand(item, event::derive)
96}
97
98#[proc_macro_derive(
103 Input,
104 attributes(sofie, input, min, max, length, range, required, unique, unconstrained)
105)]
106pub fn derive_input(item: TokenStream) -> TokenStream {
107 expand(item, input::derive)
108}
109
110#[proc_macro_attribute]
112pub fn on(arguments: TokenStream, item: TokenStream) -> TokenStream {
113 if arguments.is_empty() {
114 return item;
115 }
116 let error = syn::Error::new_spanned(
117 proc_macro2::TokenStream::from(arguments),
118 "write a bare `#[on]`: the listener's first argument's type is the event",
119 );
120 [error.into_compile_error().into(), item]
121 .into_iter()
122 .collect()
123}
124
125#[cfg(feature = "span")]
127#[proc_macro_attribute]
128pub fn span(arguments: TokenStream, item: TokenStream) -> TokenStream {
129 span::attribute(&arguments.into(), item.into()).into()
130}
131
132#[proc_macro_attribute]
134pub fn job(_arguments: TokenStream, item: TokenStream) -> TokenStream {
135 item
136}
137
138#[cfg(feature = "tasks")]
140#[proc_macro_attribute]
141pub fn task(arguments: TokenStream, item: TokenStream) -> TokenStream {
142 task::attribute(&arguments.into(), item.into()).into()
143}
144
145#[cfg(feature = "contracts")]
147#[proc_macro_attribute]
148pub fn contract(_arguments: TokenStream, item: TokenStream) -> TokenStream {
149 contracts::attribute(item.into(), contracts::Boundary::Contract).into()
150}
151
152#[cfg(feature = "gateways")]
154#[proc_macro_attribute]
155pub fn gateway(_arguments: TokenStream, item: TokenStream) -> TokenStream {
156 contracts::attribute(item.into(), contracts::Boundary::Gateway).into()
157}
158
159#[proc_macro_attribute]
174pub fn every(arguments: TokenStream, item: TokenStream) -> TokenStream {
175 every::attribute(arguments.into(), item.into()).into()
176}
177
178#[proc_macro_attribute]
180pub fn feature(_arguments: TokenStream, item: TokenStream) -> TokenStream {
181 item
182}
183
184#[cfg(feature = "fixtures")]
186#[proc_macro_attribute]
187pub fn test_app(arguments: TokenStream, item: TokenStream) -> TokenStream {
188 let function = parse_macro_input!(item as syn::ItemFn);
189 fixture::test_app(arguments.into(), &function)
190 .unwrap_or_else(syn::Error::into_compile_error)
191 .into()
192}
193
194fn expand(
195 item: TokenStream,
196 derive: fn(&DeriveInput) -> syn::Result<proc_macro2::TokenStream>,
197) -> TokenStream {
198 let input = parse_macro_input!(item as DeriveInput);
199 derive(&input)
200 .and_then(|expanded| crate_path::with_crate_path(&input, expanded))
201 .unwrap_or_else(syn::Error::into_compile_error)
202 .into()
203}