macroonz_macros/lib.rs
1//! The thin proc-macro carrier for the root recipe entrance, item-preserving attributes, and direct declarations.
2//!
3//! Recipe grammar and projection belong to the compiler's `recipe` home; the other entries use the compiler's `descriptor` home and its `door` road.
4//! What this crate adds is exactly what a proc host owns: token conversion, span custody, one compiler call, diagnostic placement, and emission — plus the facts of its own act, declared once beside each entry.
5//! Built-in recipe projections may cross this host, while an arbitrary downstream projection algorithm uses the same compiler contract from a caller-owned compiler or proc host.
6//!
7//! Each attribute expands to one exported carrier and then re-emits the item token stream it received; the carrier is inert until a consumption target invokes it, so an ordinary build compiles the item and one macro definition and nothing more.
8//! Direct declarations such as [`shadow!`](macro@shadow), [`network!`](macro@network), and [`concurrency!`](macro@concurrency) emit ordinary items where the declaration stands, inert inside nothing, because a face and a builder are not cargo.
9
10use macroonz_compiler::descriptor::door;
11use macroonz_compiler::descriptor::{Emitter, Grammar};
12use macroonz_compiler::{CrateBinding, Door, Producer, host};
13use proc_macro::TokenStream;
14
15/// Who is asking wherever the root recipe entrance refuses.
16const RECIPE_DOOR: Door = Door::declared(
17 "macroonz",
18 "macroonz.recipe",
19 "macroonz::recipe!",
20 CrateBinding::declared("macroonz"),
21 Producer {
22 namespace: "macroonz",
23 name: "macroonz-macros",
24 },
25);
26
27/// The procedural carrier behind `macroonz::recipe!`.
28///
29/// Rust requires this function-like proc entry to be public so the facade's hygienic wrapper can reach it across the package boundary.
30/// `macroonz::recipe!` is the only supported entrance; direct invocation is outside the compatibility contract and may change or break in any release without notice.
31#[doc(hidden)]
32#[proc_macro]
33pub fn __macroonz_recipe_carrier(body: TokenStream) -> TokenStream {
34 host::expand_emittable(body, |capture| {
35 macroonz_compiler::recipe::bake_wrapped(&capture, &RECIPE_DOOR)
36 })
37}
38
39/// The grammar spelling the `trials` attribute registers.
40const TRIALS_GRAMMAR: Grammar = Grammar {
41 attribute: "trials",
42};
43
44/// The grammar spelling the `mutations` attribute registers.
45const MUTATIONS_GRAMMAR: Grammar = Grammar {
46 attribute: "mutations",
47};
48
49/// The grammar spelling the `bench` attribute registers.
50const BENCH_GRAMMAR: Grammar = Grammar { attribute: "bench" };
51
52/// This crate's own act, for the trial door.
53const TRIALS_EMITTER: Emitter = Emitter {
54 namespace: "macroonz",
55 producer: "macroonz-macros",
56 door: "trials",
57};
58
59/// This crate's own act, for the bench door.
60const BENCH_EMITTER: Emitter = Emitter {
61 namespace: "macroonz",
62 producer: "macroonz-macros",
63 door: "bench",
64};
65
66/// Who is asking, wherever a `trials` expansion refuses.
67const TRIALS_DOOR: Door = Door::declared(
68 "macroonz",
69 "macroonz.trials",
70 "macroonz_macros::trials",
71 CrateBinding::declared("macroonz"),
72 Producer {
73 namespace: "macroonz",
74 name: "macroonz-macros",
75 },
76);
77
78/// Who is asking, wherever a `mutations` expansion refuses.
79const MUTATIONS_DOOR: Door = Door::declared(
80 "macroonz",
81 "macroonz.mutations",
82 "macroonz_macros::mutations",
83 CrateBinding::declared("macroonz"),
84 Producer {
85 namespace: "macroonz",
86 name: "macroonz-macros",
87 },
88);
89
90/// Who is asking, wherever a `bench` expansion refuses.
91const BENCH_DOOR: Door = Door::declared(
92 "macroonz",
93 "macroonz.bench",
94 "macroonz_macros::bench",
95 CrateBinding::declared("macroonz"),
96 Producer {
97 namespace: "macroonz",
98 name: "macroonz-macros",
99 },
100);
101
102/// The grammar spelling the `shadow` declaration registers.
103const SHADOW_GRAMMAR: Grammar = Grammar {
104 attribute: "shadow",
105};
106
107/// The grammar spelling the `network` declaration registers.
108const NETWORK_GRAMMAR: Grammar = Grammar {
109 attribute: "network",
110};
111
112/// The grammar spelling the `concurrency` declaration registers.
113const CONCURRENCY_GRAMMAR: Grammar = Grammar {
114 attribute: "concurrency",
115};
116
117/// Who is asking, wherever a `network` expansion refuses.
118const NETWORK_DOOR: Door = Door::declared(
119 "macroonz",
120 "macroonz.network",
121 "macroonz_macros::network",
122 CrateBinding::declared("macroonz"),
123 Producer {
124 namespace: "macroonz",
125 name: "macroonz-macros",
126 },
127);
128
129/// Who is asking, wherever a `concurrency` expansion refuses.
130const CONCURRENCY_DOOR: Door = Door::declared(
131 "macroonz",
132 "macroonz.concurrency",
133 "macroonz_macros::concurrency",
134 CrateBinding::declared("macroonz"),
135 Producer {
136 namespace: "macroonz",
137 name: "macroonz-macros",
138 },
139);
140
141/// Who is asking, wherever a `shadow` expansion refuses.
142const SHADOW_DOOR: Door = Door::declared(
143 "macroonz",
144 "macroonz.shadow",
145 "macroonz_macros::shadow",
146 CrateBinding::declared("macroonz"),
147 Producer {
148 namespace: "macroonz",
149 name: "macroonz-macros",
150 },
151);
152
153/// Declares a trial table beside the item this attribute sits on.
154///
155/// The body is the trial grammar, read whole by `macroonz_compiler::descriptor::trial`: the exported support name, the stamped module, the table's own name, and each aggregate seat with its rows.
156/// The expansion is one exported carrier holding the stamped table inert, followed by the item unchanged; a consumption target invokes the carrier by the declared support name and supplies its own host facts and callables there.
157///
158/// A malformed declaration expands to `compile_error!` at the offending token, carrying the compiler's own rendering of the established cause.
159#[proc_macro_attribute]
160pub fn trials(body: TokenStream, item: TokenStream) -> TokenStream {
161 let mut expanded = host::expand_on(body, item.clone(), |captured_body, captured_item| {
162 door::trials(
163 &captured_body,
164 &captured_item,
165 TRIALS_GRAMMAR,
166 TRIALS_EMITTER,
167 &TRIALS_DOOR,
168 )
169 });
170 expanded.extend(item);
171 expanded
172}
173
174/// Declares a mutation surface over the enum this attribute sits on.
175///
176/// The body is the mutation grammar, read whole by `macroonz_compiler::descriptor::mutation`: the surface's address, the evaluation family, the point and owner fact, the fact-to-claim mappings, and the operator permissions.
177/// The door completes the site from the item itself — the enum's variant list is the declared order, the unchanged operation is that order as authored, and each alternative is one adjacent transposition of it under the harness bank's `declared-order-permutation` operator family.
178/// The expansion is one exported carrier holding the rendered module as proved test-carrier cargo, followed by the item unchanged.
179///
180/// A malformed declaration, and an item that states no order this grammar can read, expand to `compile_error!` at the offending token.
181#[proc_macro_attribute]
182pub fn mutations(body: TokenStream, item: TokenStream) -> TokenStream {
183 let mut expanded = host::expand_on(body, item.clone(), |captured_body, captured_item| {
184 door::mutations(
185 &captured_body,
186 &captured_item,
187 MUTATIONS_GRAMMAR,
188 &MUTATIONS_DOOR,
189 )
190 });
191 expanded.extend(item);
192 expanded
193}
194
195/// Declares a neutral benchmark table and its typed report-reader seat beside the item this attribute sits on.
196///
197/// The body is the bench grammar, read whole by `macroonz_compiler::descriptor::bench`: the exported support name, the table function and name, the reporter module, and each row's references, axis, four exact budget values, optional formula, and observation references.
198/// The expansion is one exported carrier holding the table in its stamped seat and one target-supplied `fn(&BenchReport)` value in its opaque seat, followed by the item unchanged.
199///
200/// A malformed declaration expands to `compile_error!` at the offending token, carrying the compiler's own rendering of the established cause.
201#[proc_macro_attribute]
202pub fn bench(body: TokenStream, item: TokenStream) -> TokenStream {
203 let mut expanded = host::expand_on(body, item.clone(), |captured_body, captured_item| {
204 door::bench(
205 &captured_body,
206 &captured_item,
207 BENCH_GRAMMAR,
208 BENCH_EMITTER,
209 &BENCH_DOOR,
210 )
211 });
212 expanded.extend(item);
213 expanded
214}
215
216/// Declares the two faces of every chosen synchronization name, once, where the declaration stands.
217///
218/// The body declares the physical Loom path and a comma-separated choice of names from the compiler's stated shadow roster.
219/// Each chosen name expands to exactly the pair its author would have written by hand: the ordinary face behind `#[cfg(not(loom))]` over the standard-library path, and the shadowed face behind `#[cfg(loom)]` over the shadow path.
220/// Write the declaration once in a module of the production crate and import through that module everywhere; the crate's one remaining act is its own `[target.'cfg(loom)'.dependencies]` row, declared where it is used.
221///
222/// A name outside the roster, a malformed choice, and an empty declaration expand to `compile_error!` at the offending token, carrying the compiler's own rendering of the established cause.
223#[proc_macro]
224pub fn shadow(body: TokenStream) -> TokenStream {
225 host::expand(body, |capture| {
226 door::shadow(capture, SHADOW_GRAMMAR, &SHADOW_DOOR)
227 })
228}
229
230/// Declares a topology and its fault schedules, and expands to the builder module an author would have written by hand.
231///
232/// The body names the physical harness path, a module, a namespace, the nodes, the directed links, and each schedule's discipline as fault phrases in the sim's own vocabulary.
233/// What the tokens can know refuses at its own token; what the harness's value guards refuse still refuses there, through the generated functions' honest results.
234///
235/// A malformed declaration expands to `compile_error!` at the offending token, carrying the compiler's own rendering of the established cause.
236#[proc_macro]
237pub fn network(body: TokenStream) -> TokenStream {
238 host::expand(body, |capture| {
239 door::network(capture, NETWORK_GRAMMAR, &NETWORK_DOOR)
240 })
241}
242
243/// Declares named interleaving explorations, and expands to one generic function per row.
244///
245/// The body names the physical harness path and each row pins the facts that make a finding replayable — the population, the exhaustive ceiling, the sample count, and the seed — while the generated function takes the strand set and the transition contract at the call, handing back the exploration reading beside its concluded trial verdict.
246///
247/// A malformed declaration expands to `compile_error!` at the offending token, carrying the compiler's own rendering of the established cause.
248#[proc_macro]
249pub fn concurrency(body: TokenStream) -> TokenStream {
250 host::expand(body, |capture| {
251 door::concurrency(capture, CONCURRENCY_GRAMMAR, &CONCURRENCY_DOOR)
252 })
253}