Skip to main content

nexus_rt/codegen_audit/
helpers.rs

1//! Shared types, resources, and step functions for codegen audit.
2
3use crate::world::Resource;
4use crate::{Res, ResMut, World, WorldBuilder};
5
6// ── Resource types ───────────────────────────────────────────────
7
8/// Simple mutable counter.
9pub struct ResA(pub u64);
10impl Resource for ResA {}
11/// Secondary resource for multi-param tests.
12pub struct ResB(pub u32);
13impl Resource for ResB {}
14/// Third resource for high-arity tests.
15pub struct ResC(pub u16);
16impl Resource for ResC {}
17/// Fourth resource.
18pub struct ResD(pub u8);
19impl Resource for ResD {}
20/// Fifth resource (float).
21pub struct ResE(pub f64);
22impl Resource for ResE {}
23/// Sixth resource for high-arity tests.
24pub struct ResF(pub u64);
25impl Resource for ResF {}
26/// Seventh resource for high-arity tests.
27pub struct ResG(pub u32);
28impl Resource for ResG {}
29/// Eighth resource for high-arity tests.
30pub struct ResH(pub u16);
31impl Resource for ResH {}
32
33// ── World factory ────────────────────────────────────────────────
34
35/// Build a World pre-populated with all audit resources.
36pub fn make_world() -> World {
37    let mut wb = WorldBuilder::new();
38    wb.register(ResA(100));
39    wb.register(ResB(50));
40    wb.register(ResC(25));
41    wb.register(ResD(10));
42    wb.register(ResE(3.14));
43    wb.register(ResF(200));
44    wb.register(ResG(75));
45    wb.register(ResH(12));
46    wb.build()
47}
48
49// ═════════════════════════════════════════════════════════════════
50// Pipeline steps (by-value input)
51// ═════════════════════════════════════════════════════════════════
52
53// -- Arity 0 — pure transforms -----------------------------------
54
55pub fn add_one(x: u64) -> u64 {
56    x.wrapping_add(1)
57}
58pub fn double(x: u64) -> u64 {
59    x.wrapping_mul(2)
60}
61pub fn add_three(x: u64) -> u64 {
62    x.wrapping_add(3)
63}
64pub fn square(x: u64) -> u64 {
65    x.wrapping_mul(x)
66}
67pub fn sub_ten(x: u64) -> u64 {
68    x.wrapping_sub(10)
69}
70pub fn shr_one(x: u64) -> u64 {
71    x >> 1
72}
73pub fn xor_mask(x: u64) -> u64 {
74    x ^ 0xDEAD_BEEF
75}
76pub fn add_seven(x: u64) -> u64 {
77    x.wrapping_add(7)
78}
79pub fn triple(x: u64) -> u64 {
80    x.wrapping_mul(3)
81}
82pub fn add_forty_two(x: u64) -> u64 {
83    x.wrapping_add(42)
84}
85
86// -- Arity 1 — one Res/ResMut ------------------------------------
87
88pub fn add_res_a(a: Res<ResA>, x: u64) -> u64 {
89    x.wrapping_add(a.0)
90}
91pub fn mul_res_b(b: Res<ResB>, x: u64) -> u64 {
92    x.wrapping_mul(b.0 as u64)
93}
94pub fn write_res_a(mut a: ResMut<ResA>, x: u64) -> u64 {
95    a.0 = a.0.wrapping_add(x);
96    x
97}
98
99// -- Arity 2 ------------------------------------------------------
100
101pub fn add_both(a: Res<ResA>, b: Res<ResB>, x: u64) -> u64 {
102    x.wrapping_add(a.0).wrapping_add(b.0 as u64)
103}
104
105// -- Arity 3 ------------------------------------------------------
106
107pub fn three_params(a: Res<ResA>, b: Res<ResB>, c: Res<ResC>, x: u64) -> u64 {
108    x.wrapping_add(a.0)
109        .wrapping_add(b.0 as u64)
110        .wrapping_add(c.0 as u64)
111}
112
113// -- Arity 4 ------------------------------------------------------
114
115pub fn four_params(a: Res<ResA>, b: Res<ResB>, c: Res<ResC>, d: Res<ResD>, x: u64) -> u64 {
116    x.wrapping_add(a.0)
117        .wrapping_add(b.0 as u64)
118        .wrapping_add(c.0 as u64)
119        .wrapping_add(d.0 as u64)
120}
121
122// -- Arity 5 ------------------------------------------------------
123
124pub fn five_params(
125    a: Res<ResA>,
126    b: Res<ResB>,
127    c: Res<ResC>,
128    d: Res<ResD>,
129    e: Res<ResE>,
130    x: u64,
131) -> u64 {
132    x.wrapping_add(a.0)
133        .wrapping_add(b.0 as u64)
134        .wrapping_add(c.0 as u64)
135        .wrapping_add(d.0 as u64)
136        .wrapping_add(e.0 as u64)
137}
138
139// -- Arity 7 (8 params total with event) --------------------------
140
141pub fn eight_params(
142    a: Res<ResA>,
143    b: Res<ResB>,
144    c: Res<ResC>,
145    d: Res<ResD>,
146    e: Res<ResE>,
147    f: Res<ResF>,
148    g: Res<ResG>,
149    x: u64,
150) -> u64 {
151    x.wrapping_add(a.0)
152        .wrapping_add(b.0 as u64)
153        .wrapping_add(c.0 as u64)
154        .wrapping_add(d.0 as u64)
155        .wrapping_add(e.0 as u64)
156        .wrapping_add(f.0)
157        .wrapping_add(g.0 as u64)
158}
159
160// -- Option-producing steps ---------------------------------------
161
162pub fn maybe_positive(x: u64) -> Option<u64> {
163    if x > 0 { Some(x) } else { None }
164}
165
166pub fn checked_double(x: u64) -> Option<u64> {
167    x.checked_mul(2)
168}
169
170// -- Result-producing steps ---------------------------------------
171
172pub fn try_parse(x: u64) -> Result<u64, u32> {
173    if x < 10_000 {
174        Ok(x.wrapping_mul(2))
175    } else {
176        Err(x as u32)
177    }
178}
179
180pub fn validate(a: Res<ResA>, x: u64) -> Result<u64, u32> {
181    if x <= a.0 { Ok(x) } else { Err(x as u32) }
182}
183
184// -- Bool-producing steps -----------------------------------------
185
186pub fn is_even(x: u64) -> bool {
187    x & 1 == 0
188}
189
190// -- Tuple-producing steps ----------------------------------------
191
192pub fn split_u64(x: u64) -> (u32, u32) {
193    (x as u32, (x >> 32) as u32)
194}
195
196pub fn split_3(x: u64) -> (u32, u16, u8) {
197    (x as u32, (x >> 32) as u16, (x >> 48) as u8)
198}
199
200pub fn split_4(x: u64) -> (u32, u16, u8, u8) {
201    (x as u32, (x >> 32) as u16, (x >> 48) as u8, (x >> 56) as u8)
202}
203
204pub fn split_5(x: u64) -> (u32, u16, u8, u8, u8) {
205    (
206        x as u32,
207        (x >> 32) as u16,
208        (x >> 48) as u8,
209        (x >> 52) as u8,
210        (x >> 56) as u8,
211    )
212}
213
214// -- Sinks (return ()) --------------------------------------------
215
216pub fn consume_val(mut a: ResMut<ResA>, x: u64) {
217    a.0 = a.0.wrapping_add(x);
218}
219pub fn consume_unit(_x: ()) {}
220
221// ═════════════════════════════════════════════════════════════════
222// DAG steps (by-reference input)
223// ═════════════════════════════════════════════════════════════════
224
225pub fn ref_add_one(x: &u64) -> u64 {
226    x.wrapping_add(1)
227}
228pub fn ref_double(x: &u64) -> u64 {
229    x.wrapping_mul(2)
230}
231pub fn ref_add_three(x: &u64) -> u64 {
232    x.wrapping_add(3)
233}
234pub fn ref_square(x: &u64) -> u64 {
235    x.wrapping_mul(*x)
236}
237pub fn ref_sub_ten(x: &u64) -> u64 {
238    x.wrapping_sub(10)
239}
240pub fn ref_shr_one(x: &u64) -> u64 {
241    x >> 1
242}
243pub fn ref_xor_mask(x: &u64) -> u64 {
244    x ^ 0xDEAD_BEEF
245}
246pub fn ref_add_seven(x: &u64) -> u64 {
247    x.wrapping_add(7)
248}
249pub fn ref_triple(x: &u64) -> u64 {
250    x.wrapping_mul(3)
251}
252pub fn ref_add_forty_two(x: &u64) -> u64 {
253    x.wrapping_add(42)
254}
255
256pub fn ref_add_res_a(a: Res<ResA>, x: &u64) -> u64 {
257    x.wrapping_add(a.0)
258}
259pub fn ref_mul_res_b(b: Res<ResB>, x: &u64) -> u64 {
260    x.wrapping_mul(b.0 as u64)
261}
262pub fn ref_write_res_a(mut a: ResMut<ResA>, x: &u64) -> u64 {
263    a.0 = a.0.wrapping_add(*x);
264    *x
265}
266
267pub fn ref_add_both(a: Res<ResA>, b: Res<ResB>, x: &u64) -> u64 {
268    x.wrapping_add(a.0).wrapping_add(b.0 as u64)
269}
270
271pub fn ref_three_params(a: Res<ResA>, b: Res<ResB>, c: Res<ResC>, x: &u64) -> u64 {
272    x.wrapping_add(a.0)
273        .wrapping_add(b.0 as u64)
274        .wrapping_add(c.0 as u64)
275}
276
277pub fn ref_maybe_positive(x: &u64) -> Option<u64> {
278    if *x > 0 { Some(*x) } else { None }
279}
280
281pub fn ref_try_parse(x: &u64) -> Result<u64, u32> {
282    if *x < 10_000 {
283        Ok(x.wrapping_mul(2))
284    } else {
285        Err(*x as u32)
286    }
287}
288
289pub fn ref_is_even(x: &u64) -> bool {
290    x & 1 == 0
291}
292
293pub fn ref_split_u64(x: &u64) -> (u32, u32) {
294    (*x as u32, (x >> 32) as u32)
295}
296
297pub fn ref_split_3(x: &u64) -> (u32, u16, u8) {
298    (*x as u32, (x >> 32) as u16, (x >> 48) as u8)
299}
300
301pub fn ref_five_params(
302    a: Res<ResA>,
303    b: Res<ResB>,
304    c: Res<ResC>,
305    d: Res<ResD>,
306    e: Res<ResE>,
307    x: &u64,
308) -> u64 {
309    x.wrapping_add(a.0)
310        .wrapping_add(b.0 as u64)
311        .wrapping_add(c.0 as u64)
312        .wrapping_add(d.0 as u64)
313        .wrapping_add(e.0 as u64)
314}
315
316pub fn ref_split_5(x: &u64) -> (u32, u16, u8, u8, u8) {
317    (
318        *x as u32,
319        (x >> 32) as u16,
320        (x >> 48) as u8,
321        (x >> 52) as u8,
322        (x >> 56) as u8,
323    )
324}
325
326pub fn ref_consume(mut a: ResMut<ResA>, x: &u64) {
327    a.0 = a.0.wrapping_add(*x);
328}
329pub fn ref_consume_unit(_x: &()) {}
330
331// ═════════════════════════════════════════════════════════════════
332// Merge steps (multi-reference input)
333// ═════════════════════════════════════════════════════════════════
334
335pub fn merge_add(a: &u64, b: &u64) -> u64 {
336    a.wrapping_add(*b)
337}
338pub fn merge_mul(a: &u64, b: &u64) -> u64 {
339    a.wrapping_mul(*b)
340}
341
342pub fn merge_3(a: &u64, b: &u64, c: &u64) -> u64 {
343    a.wrapping_add(*b).wrapping_add(*c)
344}
345
346pub fn merge_4(a: &u64, b: &u64, c: &u64, d: &u64) -> u64 {
347    a.wrapping_add(*b).wrapping_add(*c).wrapping_add(*d)
348}
349
350pub fn merge_consume(mut w: ResMut<ResA>, a: &u64, b: &u64) {
351    w.0 = a.wrapping_add(*b);
352}
353
354pub fn merge_3_consume(mut w: ResMut<ResA>, a: &u64, b: &u64, c: &u64) {
355    w.0 = a.wrapping_add(*b).wrapping_add(*c);
356}
357
358// ═════════════════════════════════════════════════════════════════
359// Splat steps (tuple elements as individual args)
360// ═════════════════════════════════════════════════════════════════
361
362pub fn splat_add(a: u32, b: u32) -> u64 {
363    a as u64 + b as u64
364}
365
366pub fn splat_3(a: u32, b: u16, c: u8) -> u64 {
367    a as u64 + b as u64 + c as u64
368}
369
370pub fn splat_4(a: u32, b: u16, c: u8, d: u8) -> u64 {
371    a as u64 + b as u64 + c as u64 + d as u64
372}
373
374pub fn splat_5(a: u32, b: u16, c: u8, d: u8, e: u8) -> u64 {
375    a as u64 + b as u64 + c as u64 + d as u64 + e as u64
376}
377
378// DAG splat (by reference)
379
380pub fn ref_splat_add(a: &u32, b: &u32) -> u64 {
381    *a as u64 + *b as u64
382}
383
384pub fn ref_splat_3(a: &u32, b: &u16, c: &u8) -> u64 {
385    *a as u64 + *b as u64 + *c as u64
386}
387
388pub fn ref_splat_5(a: &u32, b: &u16, c: &u8, d: &u8, e: &u8) -> u64 {
389    *a as u64 + *b as u64 + *c as u64 + *d as u64 + *e as u64
390}