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;
15#[cfg(test)]
17#[path = "../../sofie-core/src/case.rs"]
18mod core_case;
19mod crate_path;
20mod enumeration;
21mod event;
22mod every;
23#[cfg(feature = "factories")]
24mod factory;
25#[cfg(feature = "fixtures")]
26mod fixture;
27mod input;
28#[cfg(feature = "joins")]
29mod joins;
30#[cfg(feature = "retention")]
31mod pruned;
32mod read_model;
33#[cfg(feature = "remote-contracts")]
34mod remote;
35mod sensitive;
36mod serialize;
37mod shape;
38#[cfg(feature = "span")]
39mod span;
40#[cfg(feature = "tasks")]
41mod task;
42mod value;
43
44#[proc_macro_derive(
50 Aggregate,
51 attributes(
52 sofie, owner, aggregate, min, max, length, range, required, unique, expose, mirror,
53 sensitive
54 )
55)]
56pub fn derive_aggregate(item: TokenStream) -> TokenStream {
57 expand(item, aggregate::derive)
58}
59
60#[cfg(feature = "children")]
62#[proc_macro_derive(Child, attributes(sofie, min, max, length, range, required))]
63pub fn derive_child(item: TokenStream) -> TokenStream {
64 expand(item, children::derive)
65}
66
67#[proc_macro_derive(Value, attributes(sofie, sensitive))]
71pub fn derive_value(item: TokenStream) -> TokenStream {
72 expand(item, value::derive)
73}
74
75#[cfg(feature = "config")]
78#[proc_macro_derive(Config, attributes(sofie))]
79pub fn derive_config(item: TokenStream) -> TokenStream {
80 expand(item, config::derive)
81}
82
83#[proc_macro_derive(Enum, attributes(sofie, to, tone))]
85pub fn derive_enum(item: TokenStream) -> TokenStream {
86 expand(item, enumeration::derive)
87}
88
89#[proc_macro_derive(ReadModel, attributes(sofie, read, sensitive))]
93pub fn derive_read_model(item: TokenStream) -> TokenStream {
94 expand(item, read_model::derive)
95}
96
97#[proc_macro_derive(Event, attributes(sofie))]
98pub fn derive_event(item: TokenStream) -> TokenStream {
99 expand(item, event::derive)
100}
101
102#[proc_macro_derive(
107 Input,
108 attributes(sofie, input, min, max, length, range, required, unique, unconstrained)
109)]
110pub fn derive_input(item: TokenStream) -> TokenStream {
111 expand(item, input::derive)
112}
113
114#[proc_macro_attribute]
116pub fn on(arguments: TokenStream, item: TokenStream) -> TokenStream {
117 if arguments.is_empty() {
118 return item;
119 }
120 let error = syn::Error::new_spanned(
121 proc_macro2::TokenStream::from(arguments),
122 "write a bare `#[on]`: the listener's first argument's type is the event",
123 );
124 [error.into_compile_error().into(), item]
125 .into_iter()
126 .collect()
127}
128
129#[cfg(feature = "span")]
131#[proc_macro_attribute]
132pub fn span(arguments: TokenStream, item: TokenStream) -> TokenStream {
133 span::attribute(&arguments.into(), item.into()).into()
134}
135
136#[proc_macro_attribute]
138pub fn job(_arguments: TokenStream, item: TokenStream) -> TokenStream {
139 item
140}
141
142#[cfg(feature = "tasks")]
144#[proc_macro_attribute]
145pub fn task(arguments: TokenStream, item: TokenStream) -> TokenStream {
146 task::attribute(&arguments.into(), item.into()).into()
147}
148
149#[cfg(feature = "contracts")]
151#[proc_macro_attribute]
152pub fn contract(_arguments: TokenStream, item: TokenStream) -> TokenStream {
153 contracts::attribute(item.into(), contracts::Boundary::Contract).into()
154}
155
156#[cfg(feature = "gateways")]
158#[proc_macro_attribute]
159pub fn gateway(_arguments: TokenStream, item: TokenStream) -> TokenStream {
160 contracts::attribute(item.into(), contracts::Boundary::Gateway).into()
161}
162
163#[proc_macro_attribute]
178pub fn every(arguments: TokenStream, item: TokenStream) -> TokenStream {
179 every::attribute(arguments.into(), item.into()).into()
180}
181
182#[proc_macro_attribute]
184pub fn feature(_arguments: TokenStream, item: TokenStream) -> TokenStream {
185 item
186}
187
188#[cfg(feature = "fixtures")]
190#[proc_macro_attribute]
191pub fn test_app(arguments: TokenStream, item: TokenStream) -> TokenStream {
192 let function = parse_macro_input!(item as syn::ItemFn);
193 fixture::test_app(arguments.into(), &function)
194 .unwrap_or_else(syn::Error::into_compile_error)
195 .into()
196}
197
198fn expand(
199 item: TokenStream,
200 derive: fn(&DeriveInput) -> syn::Result<proc_macro2::TokenStream>,
201) -> TokenStream {
202 let input = parse_macro_input!(item as DeriveInput);
203 derive(&input)
204 .and_then(|expanded| crate_path::with_crate_path(&input, expanded))
205 .unwrap_or_else(syn::Error::into_compile_error)
206 .into()
207}