1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
//! The RAW handler ABI (bc#76): a de-boxed handler boundary so a generated typed module
//! materializes a struct DIRECTLY from the wire payload, with no intermediate dynamic
//! `Value`/`Value::Obj` tree on the row data plane.
//!
//! # Why this exists (the boxing #75 left)
//!
//! The typed codegen (#47/#48) materialized structs from an ALREADY-BOXED `Value`:
//!
//! ```ignore
//! fn marshal_T0(raw: &Value) -> Result<T0, BehaviorError> // raw is a Value::Obj tree
//! ```
//!
//! The consumer's read handler first built the full dynamic `Value` tree and the generated
//! module then WALKED it into a struct — ADDING a `Value`->struct conversion on top of the
//! boxing instead of REPLACING it. The residual ~22% Rust gap #75 measured is exactly that
//! `Value`/`Value::Obj` deep-clone at the handler ABI boundary (Rust felt it most: the
//! `Value` enum boxes every `Obj` pair into a heap `Vec<(String, Value)>` that is cloned at
//! the ABI, then re-walked).
//!
//! bc's conformance handlers return a `Value` mock, so the suite structurally could not see
//! what the consumer's real handler did BEFORE the `Value` reached the module — the blind
//! spot that let bc#47's B2 layering recur one layer out as bc#76.
//!
//! # The seam
//!
//! A RAW handler yields a [`RawValue`] — a native-backed accessor tree that is NOT a
//! `Value`. The generated raw marshaller matches on it (scalar / [`RawRow`] / arr) straight
//! into the concrete struct. The dynamic `Value` tree never exists on the row data plane;
//! boxing is REPLACED, not layered. `RawRow::field` is the monomorphized wire read a
//! hand-written v1-native struct-from-row would do.
use crateBehaviorError;
use crateValue;
/// A handler result on the RAW data plane — deliberately NOT a [`Value`]: the whole point of
/// #76 is that the dynamic `Value`/`Value::Obj` tree is never built here. A real consumer's
/// handler returns its native wire shape as a [`RawValue`] with no `Value` allocation.
/// The object accessor on the raw data plane: a direct native field read that materializes
/// NO `Value::Obj`. bc conformance uses this native `Vec`-backed row (no real wire format) so
/// the generated raw marshaller exercises the de-boxed path; a real consumer implements the
/// same shape over its wire payload (e.g. an AttributeValue map).
/// A RAW handler execution result. `Ok` carries a [`RawValue`] (native-backed), NOT a boxed
/// `Value` — that is the whole de-box.
/// The RAW handler registry seam: like `ComponentExec`, but the handler returns a
/// [`RawValue`] (native-backed) instead of a boxed `Value`. A generated raw-ABI module
/// dispatches through this and materializes structs directly from the [`RawValue`] — no
/// dynamic `Value` tree on the row data plane.
/// Blanket forwarding impl so a trait-object raw handler (`&mut dyn RawComponentExec`)
/// satisfies [`RawComponentExec`] — mirrors the `&mut dyn ComponentExec` blanket (bc#68) so a
/// consumer holding its raw registry behind a trait object drives the generated raw module
/// through the unchanged generic entry.
// ── Native PORTS ABI (bc 0.5.0) ──────────────────────────────────────────────────────────
//
// The RESULT side above (`RawComponentExec`) de-boxed the handler RESULT. The PORTS side of
// every generated componentRef still built a generic key-value container: `vec![("PK"
// .to_string(), val), …]` — a `Vec` alloc + a heap `String` key per port + a boxed `Value`
// per port — then a generic dispatch. That generic key-value plumbing is the residual cost.
//
// The native-ports emitter builds, per node, a NATIVE ports struct (typed fields, direct
// construction, no `Vec`/`String`-key/`Value` boxing) and dispatches it through this seam. The
// struct is passed behind a [`PortReader`] trait object so a consumer reads ports by name
// (boxing one field on demand) or downcasts to its own type on the hot path. The generic
// `ComponentExec(ports: &[(String, Value)])` path stays as an additive fallback.
/// The optional uniform read accessor a generated native ports struct implements so a consumer
/// that does not downcast can still read ports by name. Reading a statically-typed field this
/// way clones/boxes ONLY that one field into a `Value` on demand (no `Vec`, no eager boxing of
/// every port) — a hot-path consumer downcasts (`as_any`) and reads the typed fields directly.
/// The NATIVE-PORTS handler registry seam: the handler receives the generated native ports
/// struct behind a [`PortReader`] and returns an `ExecOutcome` (a boxed `Value` RESULT — the
/// UNTYPED straight-line path has no target struct to de-box the result into, and returns the
/// boxed `Value` as the component output, exactly as the generic path does). NO generic
/// `Vec<(String, Value)>` port CONTAINER is built on the port plane — that is the de-plumb.
/// Blanket forwarding impl so a trait-object native handler (`&mut dyn NativeComponentExec`)
/// satisfies [`NativeComponentExec`] (mirrors the `&mut dyn ComponentExec` blanket, bc#68).
// ── Combined NATIVE-ports + RAW-result ABI (bc#77, the 1.0 read de-box) ────────────────────
//
// [`NativeComponentExec`] de-plumbed the PORT container but still returns a boxed `Value`
// RESULT. [`RawComponentExec`] de-boxes the RESULT but keeps the generic `Vec<(String, Value)>`
// PORT container in AND is driven by `run_plan` — whose relation-child skip-gate reads the
// PARENT's boxed result; a struct-native (nil) parent makes typed relationSingle / nestedBatchGet
// diverge from `run_behavior` (graphddb#323 / bc#74).
//
// This seam COMBINES both halves: the handler receives the generated per-node NATIVE ports
// struct (behind [`PortReader`] — no `Vec<(String, Value)>`) AND returns a native [`RawValue`]
// ([`RawOutcome`] — no boxed `Value` result tree). The generated combined read runner drives the
// nodes INLINE (sequential, no `run_plan`): each node's result is materialized DIRECTLY into its
// outType struct via `marshal_raw_T*`, node results live as struct locals, and a relation child
// reads the parent's REAL struct result inline — so relationSingle / connection reads converge
// with `run_behavior`. Zero boxed `Value` end-to-end on both the port AND row plane.
/// The COVERED-path port accessor (bc#94): the by-name read a combined handler uses, WITHOUT the
/// dynamic [`PortReader::as_any`] downcast hook. The generated combined runner passes each node's
/// CONCRETE ports struct to the handler by **direct generic instantiation** (`&P` where
/// `P: PortReaderT`, monomorphized per node) — never behind `&dyn`, never via `as_any`/`downcast`.
/// A `PortReaderT` handler still reads a port by name (boxing that one field on demand) if it does
/// not want to name the concrete struct type, but the SEAM itself carries no `dyn`/`as_any`: the
/// concrete type flows through monomorphization. (`PortReader` — with `as_any` — stays for the
/// UNCOVERED [`NativeComponentExec`] path, retired later.)
/// The combined handler registry seam (bc#94, nativized): native ports in (a CONCRETE `&P`, passed
/// by monomorphized generic instantiation — no `&dyn`, no `as_any`/`downcast`), [`RawValue`] out.
///
/// `exec_native_raw` takes `&self` (not `&mut self`): the covered runner passes `&H`, so a `Sync`
/// handler parallelizes across the bc#87 static-parallel stage with NO forced `Mutex` serialization
/// (the generic seam is `&self`; a handler needing interior mutation uses its own `Sync` interior
/// type — e.g. an atomic/`Mutex` field — rather than the seam forcing `&mut self` on every caller).
/// Lower a dynamic `Value` into the equivalent native-backed [`RawValue`]. This is the
/// ADAPTER bc's conformance uses to feed the RAW path from the SAME vectors the boxed path
/// uses (so behavior-equality is checked against `run_behavior` on identical data). It is a
/// TEST/BENCH-ADAPTER that lives OFF the hot path: a real consumer never builds a `Value`
/// first — it produces [`RawValue`] from its wire payload directly. The de-box win is
/// measured against v1-native precisely because production skips this step.
/// Build a MISSING_PROP `BehaviorError` (symmetric with the boxed marshaller's fail-closed
/// path) for a raw marshaller. Kept here so the generated raw code raises the same coded
/// failure as `run_behavior`.
/// Build a TYPE_MISMATCH `BehaviorError` for a raw marshaller.