Skip to main content

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}