macroonz_harness/descriptor/gate.rs
1//! The pre-typecheck gate: where a producer's expected schema identity meets the one this harness publishes, before either side's material reaches type checking.
2//!
3//! A mismatch is one precise loud break rather than a cascade of field errors inside a generated table.
4//! That is why the comparison is a macro arm: a `macro_rules!` pattern matches tokens, so it can refuse before the tokens it guards are parsed as Rust at all.
5//! It is also why the pin crosses as decimal byte values — an unsuffixed integer has exactly one rendering, and a byte string has many.
6//!
7//! The gate is semantically ignorant of the deferred seat on purpose: it transports or it withholds, and it never reads.
8//! A door that parsed the cargo would be a second authority over a vocabulary it does not own.
9//!
10//! The three drifts and where each dies: pair incoherence dies here, with the refusing arm telling whoever meets it how the pin is rewritten; joint staleness dies in `harness/tests/published_schema_currency/`; a changed constructor shape dies at the compiler as ordinary type errors before any trial runs.
11
12/// The generated-support schema identity this harness publishes, as raw bytes.
13///
14/// One side of the two-sided pin, and the same thirty-two values each gate arm carries as literal tokens.
15/// A `macro_rules!` arm matches tokens and cannot read a constant, so each arm carries the digits itself and the currency lane is what keeps the copies coherent.
16///
17/// It is deliberately not a [`GeneratedSupportSchemaId`](crate::descriptor::GeneratedSupportSchemaId), even though these bytes came off that derivation: a raw checked-in copy neither derives from the current declaration nor reifies an address whose derivation a caller established.
18pub const PUBLISHED_GENERATED_SUPPORT_SCHEMA_ID: &[u8; 32] = &[
19 185, 251, 251, 45, 168, 146, 85, 42, 248, 177, 196, 48, 117, 229, 207, 5, 84, 120, 104, 25,
20 150, 41, 202, 2, 243, 73, 31, 148, 241, 22, 122, 34,
21];
22
23/// Guards one generated support delivery: compares the producer's expected schema identity against the published one, and releases either the trial/deferred pair or the benchmark/reporter pair only when the two agree.
24///
25/// # The grammar
26///
27/// ```text
28/// generated_support! {
29/// expected: [<the thirty-two published bytes, in decimal>],
30/// harness: <path>,
31/// trials: { <the trial_table! payload, verbatim> },
32/// deferred: { <opaque token trees, verbatim> },
33/// }
34///
35/// generated_support! {
36/// expected: [<the thirty-two published bytes, in decimal>],
37/// harness: <path>,
38/// benches: { <the bench_table! payload, verbatim> },
39/// reporter: { <opaque token trees, verbatim> },
40/// }
41/// ```
42///
43/// - `expected:` is the producer's own copy of the published identity, as thirty-two unsuffixed decimal byte values.
44/// Exactly one roster opens the gate; every other roster reaches the refusing arm.
45/// - `harness:` is the path this crate is reached by at the invocation site.
46/// The grammar captures its root and remaining segments separately, because Rust permits a repeated identifier sequence to be extended while a captured path fragment cannot be.
47/// - `trials:` is the row road, whose grammar is [`trial_table!`](crate::trial_table)'s exhaustively and which this gate neither reads nor rewrites.
48/// The seat may be empty: a producer whose whole cargo was deferred writes `trials: { }`, the matched arm stamps no table, and nothing is missing.
49/// - `deferred:` is the opaque seat, forwarded verbatim on the matched road and withheld entirely on the refusing one.
50/// - `benches:` is the benchmark-table road, whose grammar is [`bench_table!`](crate::bench_table)'s and whose admitted table is nonempty.
51/// - `reporter:` is opaque benchmark-target cargo, released inside the same matched arm as the benchmark table.
52///
53/// Both seats of the selected form are always written, in that order.
54/// Neither is optional: a seat a producer could omit is a seat it could place somewhere the pin does not reach.
55///
56/// # Authority
57///
58/// The declared harness path is load-bearing rather than decorative: the expansion writes one item naming this crate's schema-identity type through both the declared path and `$crate`, and the two must be one type.
59/// A declaration that names another crate, or a path the consuming crate does not have, refuses at the door.
60///
61/// Agreement here means the two published sides are coherent, and nothing more.
62/// Releasing cargo is transport and never endorsement: the gate says the pin matched, and says nothing about opaque tokens it never read.
63///
64/// The `@`-prefixed rules below are internal transcriptions, not invocation forms.
65/// The forms above are text rather than compiled examples, because compiled rows need bindings that live on the challenge side.
66#[macro_export]
67macro_rules! generated_support {
68 (
69 expected: [
70 185, 251, 251, 45, 168, 146, 85, 42, 248, 177, 196, 48, 117, 229, 207, 5,
71 84, 120, 104, 25, 150, 41, 202, 2, 243, 73, 31, 148, 241, 22, 122, 34,
72 ],
73 harness: $harness:ident $(:: $harness_segment:ident)*,
74 trials: { $($trials:tt)* },
75 deferred: { $($deferred:tt)* },
76 ) => {
77 // The declared harness path, proven to name THIS crate: one type, reached both ways, and a
78 // function pointer that exists only if the two roads arrive at it. A wrong path refuses here, at
79 // the door, rather than as an unresolved path somewhere inside either seat.
80 const _: fn(
81 $harness $(:: $harness_segment)* :: descriptor::GeneratedSupportSchemaId,
82 ) -> $crate::descriptor::GeneratedSupportSchemaId = ::core::convert::identity;
83
84 $crate::generated_support! { @trials $($trials)* }
85
86 // The deferred seat, verbatim, released INSIDE the matched arm — so the pin that governs the
87 // constructors above governs this cargo by the same act rather than by a second arm that agreed
88 // with the first.
89 $($deferred)*
90 };
91
92 (
93 expected: [
94 185, 251, 251, 45, 168, 146, 85, 42, 248, 177, 196, 48, 117, 229, 207, 5,
95 84, 120, 104, 25, 150, 41, 202, 2, 243, 73, 31, 148, 241, 22, 122, 34,
96 ],
97 harness: $harness:ident $(:: $harness_segment:ident)*,
98 benches: { $($benches:tt)* },
99 reporter: { $($reporter:tt)* },
100 ) => {
101 const _: fn(
102 $harness $(:: $harness_segment)* :: descriptor::GeneratedSupportSchemaId,
103 ) -> $crate::descriptor::GeneratedSupportSchemaId = ::core::convert::identity;
104
105 $crate::generated_support! { @benches $($benches)* }
106 $($reporter)*
107 };
108
109 // Pair incoherence: the producer's expectation is a literal, and it is not the published one. ONE
110 // diagnostic, both sides shown, and no seat forwarded — the constructors and the deferred cargo are
111 // bound here and dropped here.
112 //
113 // The sentence names this macro and no crate path: a consumer may rename this dependency, and a
114 // compiler message has no way to learn the name it was renamed to.
115 (
116 expected: [$($expected:literal),* $(,)?],
117 harness: $harness:ident $(:: $harness_segment:ident)*,
118 trials: { $($trials:tt)* },
119 deferred: { $($deferred:tt)* },
120 ) => {
121 ::core::compile_error!(::core::concat!(
122 "generated_support!: the producer's expected generated-support schema identity is \
123 not the one this harness publishes, so the published pair is incoherent and \
124 nothing this door was handed reaches the compiler: the trial constructors and \
125 the deferred cargo are withheld together, because one arm releases both seats \
126 and this is not that arm. Producer expected: ",
127 ::core::stringify!([$($expected),*]),
128 ". Published here: ",
129 ::core::stringify!([
130 185, 251, 251, 45, 168, 146, 85, 42, 248, 177, 196, 48, 117, 229, 207, 5,
131 84, 120, 104, 25, 150, 41, 202, 2, 243, 73, 31, 148, 241, 22, 122, 34,
132 ]),
133 ". Declared harness: ",
134 ::core::stringify!($harness $(:: $harness_segment)*),
135 ". Both sides are rewritten together, in one change: derive the current value \
136 from the harness's own published schema declaration, write it into the \
137 producer's expectation and into this harness's published literal, and commit \
138 the pair. A version-mixed consumer, a partial rewrite, and a hand edit to one \
139 side are the three shapes this refusal has."
140 ));
141 };
142
143 (
144 expected: [$($expected:literal),* $(,)?],
145 harness: $harness:ident $(:: $harness_segment:ident)*,
146 benches: { $($benches:tt)* },
147 reporter: { $($reporter:tt)* },
148 ) => {
149 ::core::compile_error!(::core::concat!(
150 "generated_support!: the producer's expected generated-support schema identity is \
151 not the one this harness publishes, so the benchmark table and reporter cargo are \
152 withheld together. Producer expected: ",
153 ::core::stringify!([$($expected),*]),
154 ". Published here: ",
155 ::core::stringify!([
156 185, 251, 251, 45, 168, 146, 85, 42, 248, 177, 196, 48, 117, 229, 207, 5,
157 84, 120, 104, 25, 150, 41, 202, 2, 243, 73, 31, 148, 241, 22, 122, 34,
158 ]),
159 ". Declared harness: ",
160 ::core::stringify!($harness $(:: $harness_segment)*),
161 ". Derive the current value from the harness's published schema declaration and \
162 rewrite both published holders together."
163 ));
164 };
165
166 // An empty trials seat carried no rows, so it stamps nothing at all: the alternative would be handing
167 // the stamp an empty declaration, which is not a form the stamp's grammar has.
168 (@trials) => {};
169
170 // A carried seat is the stamp's grammar, forwarded whole. One or more tokens, so this rule and the one
171 // above partition the seat between them.
172 (@trials $($trials:tt)+) => {
173 $crate::trial_table! { $($trials)+ }
174 };
175
176 (@benches $($benches:tt)+) => {
177 $crate::bench_table! { $($benches)+ }
178 };
179}