Skip to main content

nexus_rt/codegen_audit/
adapters.rs

1//! Adapter, combinator, handler, and template codegen audit cases.
2//!
3//! Categories 23-25 from the assembly audit plan.
4
5#![allow(clippy::type_complexity)]
6#![allow(unused_variables)]
7
8use super::helpers::*;
9use crate::adapt::{Adapt, ByRef, Cloned, Owned};
10use crate::catch_unwind::CatchAssertUnwindSafe;
11use crate::template::{CallbackTemplate, HandlerTemplate};
12use crate::{
13    Broadcast, Handler, IntoCallback, IntoHandler, Res, ResMut, World, callback_blueprint, fan_out,
14    handler_blueprint,
15};
16
17// ═══════════════════════════════════════════════════════════════════
18// 23. Adapters
19// ═══════════════════════════════════════════════════════════════════
20
21// -- ByRef: owned → borrowed dispatch --
22
23fn ref_handler_add(a: Res<ResA>, x: &u64) {
24    let _ = a.0.wrapping_add(*x);
25}
26
27#[inline(never)]
28pub fn adapt_by_ref(world: &mut World, input: u64) {
29    let reg = world.registry();
30    let inner = ref_handler_add.into_handler(&reg);
31    let mut h = ByRef(inner);
32    h.run(world, input);
33}
34
35// -- Cloned: borrowed → owned dispatch --
36
37fn owned_handler_add(mut a: ResMut<ResA>, x: u64) {
38    a.0 = a.0.wrapping_add(x);
39}
40
41#[inline(never)]
42pub fn adapt_cloned(world: &mut World, input: &u64) {
43    let reg = world.registry();
44    let inner = owned_handler_add.into_handler(&reg);
45    let mut h = Cloned(inner);
46    h.run(world, input);
47}
48
49// -- Adapt: decode adapter --
50
51#[inline(never)]
52pub fn adapt_decode(world: &mut World, input: u64) {
53    let reg = world.registry();
54    let inner = owned_handler_add.into_handler(&reg);
55    let mut h = Adapt::new(|wire: u64| if wire > 0 { Some(wire) } else { None }, inner);
56    h.run(world, input);
57}
58
59#[inline(never)]
60pub fn adapt_decode_skip(world: &mut World, input: u64) {
61    let reg = world.registry();
62    let inner = owned_handler_add.into_handler(&reg);
63    let mut h = Adapt::new(
64        |wire: u64| {
65            if wire < 100 {
66                Some(wire.wrapping_mul(2))
67            } else {
68                None
69            }
70        },
71        inner,
72    );
73    // Half the inputs will be skipped — interesting for branch prediction codegen.
74    h.run(world, input);
75}
76
77// ═══════════════════════════════════════════════════════════════════
78// 24. Combinators (FanOut, Broadcast)
79// ═══════════════════════════════════════════════════════════════════
80
81#[inline(never)]
82pub fn fanout_2(world: &mut World, input: u64) {
83    let reg = world.registry();
84    let h1 = ref_handler_add.into_handler(&reg);
85    let h2 = ref_handler_add.into_handler(&reg);
86    let mut fan = fan_out!(h1, h2);
87    fan.run(world, input);
88}
89
90#[inline(never)]
91pub fn fanout_4(world: &mut World, input: u64) {
92    let reg = world.registry();
93    let h1 = ref_handler_add.into_handler(&reg);
94    let h2 = ref_handler_add.into_handler(&reg);
95    let h3 = ref_handler_add.into_handler(&reg);
96    let h4 = ref_handler_add.into_handler(&reg);
97    let mut fan = fan_out!(h1, h2, h3, h4);
98    fan.run(world, input);
99}
100
101#[inline(never)]
102pub fn broadcast_2(world: &mut World, input: u64) {
103    let reg = world.registry();
104    let h1 = ref_handler_add.into_handler(&reg);
105    let h2 = ref_handler_add.into_handler(&reg);
106    let mut bc = Broadcast::<u64>::new();
107    bc.add(h1);
108    bc.add(h2);
109    bc.run(world, input);
110}
111
112#[inline(never)]
113pub fn broadcast_4(world: &mut World, input: u64) {
114    let reg = world.registry();
115    let h1 = ref_handler_add.into_handler(&reg);
116    let h2 = ref_handler_add.into_handler(&reg);
117    let h3 = ref_handler_add.into_handler(&reg);
118    let h4 = ref_handler_add.into_handler(&reg);
119    let mut bc = Broadcast::<u64>::new();
120    bc.add(h1);
121    bc.add(h2);
122    bc.add(h3);
123    bc.add(h4);
124    bc.run(world, input);
125}
126
127// ═══════════════════════════════════════════════════════════════════
128// 25. Handlers & templates
129// ═══════════════════════════════════════════════════════════════════
130
131// -- Direct IntoHandler dispatch --
132
133fn handler_1_param(a: Res<ResA>, x: u64) {
134    let _ = a.0.wrapping_add(x);
135}
136fn handler_2_param(a: Res<ResA>, b: Res<ResB>, x: u64) {
137    let _ = a.0.wrapping_add(b.0 as u64).wrapping_add(x);
138}
139fn handler_3_param(a: Res<ResA>, b: Res<ResB>, c: Res<ResC>, x: u64) {
140    let _ = a.0.wrapping_add(b.0 as u64).wrapping_add(c.0 as u64);
141}
142
143#[inline(never)]
144pub fn handler_0_param_dispatch(world: &mut World, input: u64) {
145    let reg = world.registry();
146    let mut h = owned_handler_add.into_handler(&reg);
147    h.run(world, input);
148}
149
150#[inline(never)]
151pub fn handler_1_param_dispatch(world: &mut World, input: u64) {
152    let reg = world.registry();
153    let mut h = handler_1_param.into_handler(&reg);
154    h.run(world, input);
155}
156
157#[inline(never)]
158pub fn handler_2_param_dispatch(world: &mut World, input: u64) {
159    let reg = world.registry();
160    let mut h = handler_2_param.into_handler(&reg);
161    h.run(world, input);
162}
163
164#[inline(never)]
165pub fn handler_3_param_dispatch(world: &mut World, input: u64) {
166    let reg = world.registry();
167    let mut h = handler_3_param.into_handler(&reg);
168    h.run(world, input);
169}
170
171// -- Virtual (boxed) dispatch --
172
173#[inline(never)]
174pub fn handler_virtual_dispatch(world: &mut World, input: u64) {
175    let reg = world.registry();
176    let mut h: Box<dyn Handler<u64>> = Box::new(owned_handler_add.into_handler(&reg));
177    h.run(world, input);
178}
179
180// -- CatchAssertUnwindSafe --
181
182#[inline(never)]
183pub fn handler_catch_unwind(world: &mut World, input: u64) {
184    let reg = world.registry();
185    let inner = owned_handler_add.into_handler(&reg);
186    let mut h = CatchAssertUnwindSafe::new(inner);
187    h.run(world, input);
188}
189
190// -- HandlerTemplate: resolve once, stamp many --
191
192handler_blueprint!(TickBlueprint, Event = u64, Params = (ResMut<'static, ResA>,));
193
194fn tick_handler(mut a: ResMut<ResA>, x: u64) {
195    a.0 = a.0.wrapping_add(x);
196}
197
198#[inline(never)]
199pub fn template_generate_and_dispatch(world: &mut World, input: u64) {
200    let reg = world.registry();
201    let tmpl = HandlerTemplate::<TickBlueprint>::new(tick_handler, &reg);
202    let mut h = tmpl.generate();
203    h.run(world, input);
204}
205
206#[inline(never)]
207pub fn template_stamp_5(world: &mut World, input: u64) {
208    let reg = world.registry();
209    let tmpl = HandlerTemplate::<TickBlueprint>::new(tick_handler, &reg);
210    let mut h0 = tmpl.generate();
211    let mut h1 = tmpl.generate();
212    let mut h2 = tmpl.generate();
213    let mut h3 = tmpl.generate();
214    let mut h4 = tmpl.generate();
215    h0.run(world, input);
216    h1.run(world, input.wrapping_add(1));
217    h2.run(world, input.wrapping_add(2));
218    h3.run(world, input.wrapping_add(3));
219    h4.run(world, input.wrapping_add(4));
220}
221
222// ═══════════════════════════════════════════════════════════════════
223// Remaining gaps
224// ═══════════════════════════════════════════════════════════════════
225
226// ---- 23.3: Cloned with String (heap clone) ----
227
228fn string_handler(mut a: ResMut<ResA>, x: String) {
229    a.0 = x.len() as u64;
230}
231
232#[inline(never)]
233pub fn adapt_cloned_string(world: &mut World, input: &String) {
234    let reg = world.registry();
235    let inner = string_handler.into_handler(&reg);
236    let mut h = Cloned(inner);
237    h.run(world, input);
238}
239
240// ---- 23.4: Owned adapter (&str → String) ----
241
242#[inline(never)]
243pub fn adapt_owned_str(world: &mut World, input: &str) {
244    let reg = world.registry();
245    let inner = string_handler.into_handler(&reg);
246    let mut h = Owned::<_, str>::new(inner);
247    h.run(world, input);
248}
249
250// ---- 23.5: nested adapter (Cloned(ByRef(inner))) ----
251
252#[inline(never)]
253pub fn adapt_nested(world: &mut World, input: &u64) {
254    let reg = world.registry();
255    let inner = ref_handler_add.into_handler(&reg);
256    // Cloned: &u64 → u64 (copy), ByRef: u64 → &u64 → inner
257    // Two-adapter round-trip: borrow → clone → reborrow
258    let mut h = Cloned(ByRef(inner));
259    h.run(world, input);
260}
261
262// ---- 23.8: fan_out with 8 handlers ----
263
264#[inline(never)]
265pub fn fanout_8(world: &mut World, input: u64) {
266    let reg = world.registry();
267    let h1 = ref_handler_add.into_handler(&reg);
268    let h2 = ref_handler_add.into_handler(&reg);
269    let h3 = ref_handler_add.into_handler(&reg);
270    let h4 = ref_handler_add.into_handler(&reg);
271    let h5 = ref_handler_add.into_handler(&reg);
272    let h6 = ref_handler_add.into_handler(&reg);
273    let h7 = ref_handler_add.into_handler(&reg);
274    let h8 = ref_handler_add.into_handler(&reg);
275    let mut fan = fan_out!(h1, h2, h3, h4, h5, h6, h7, h8);
276    fan.run(world, input);
277}
278
279// ---- 23.9: broadcast with 3 handlers ----
280
281#[inline(never)]
282pub fn broadcast_3(world: &mut World, input: u64) {
283    let reg = world.registry();
284    let h1 = ref_handler_add.into_handler(&reg);
285    let h2 = ref_handler_add.into_handler(&reg);
286    let h3 = ref_handler_add.into_handler(&reg);
287    let mut bc = Broadcast::<u64>::new();
288    bc.add(h1);
289    bc.add(h2);
290    bc.add(h3);
291    bc.run(world, input);
292}
293
294// ---- 23.10: adapters inside fan_out ----
295
296#[inline(never)]
297pub fn adapt_in_fanout(world: &mut World, input: u64) {
298    let reg = world.registry();
299    let h1 = ref_handler_add.into_handler(&reg);
300    let h2 = owned_handler_add.into_handler(&reg);
301    let h3 = ref_handler_add.into_handler(&reg);
302    // Cloned: &u64 → u64 → owned_handler, plain ref handlers
303    let mut fan = fan_out!(Cloned(h2), h1, h3);
304    fan.run(world, input);
305}
306
307// ---- 24.4: Callback dispatch (context + params) ----
308
309struct CounterCtx {
310    count: u64,
311}
312
313fn callback_handler(ctx: &mut CounterCtx, mut a: ResMut<ResA>, x: u64) {
314    ctx.count += 1;
315    a.0 = a.0.wrapping_add(x).wrapping_add(ctx.count);
316}
317
318#[inline(never)]
319pub fn callback_dispatch(world: &mut World, input: u64) {
320    let reg = world.registry();
321    let mut h = callback_handler.into_callback(CounterCtx { count: 0 }, &reg);
322    h.run(world, input);
323}
324
325// ---- 24.7: CallbackTemplate dispatch ----
326
327callback_blueprint!(CountBlueprint, Context = CounterCtx, Event = u64, Params = (ResMut<'static, ResA>,));
328
329fn count_tick(ctx: &mut CounterCtx, mut a: ResMut<ResA>, x: u64) {
330    ctx.count += 1;
331    a.0 = a.0.wrapping_add(x).wrapping_add(ctx.count);
332}
333
334#[inline(never)]
335pub fn callback_template_dispatch(world: &mut World, input: u64) {
336    let reg = world.registry();
337    let tmpl = CallbackTemplate::<CountBlueprint>::new(count_tick, &reg);
338    let mut h = tmpl.generate(CounterCtx { count: 0 });
339    h.run(world, input);
340}