Commit a29faa8
feat(stdlib/json): v0.3 — RSR rewire to hpm-json-rsr Zig FFI (#421)
## Summary
Completes the long-deferred `parse: String -> Option<HpmJsonValue>`
bridge in `stdlib/json.affine` by routing through the
**`hyperpolymath/hpm-json-rsr` Zig FFI** (11 exports) instead of
hand-rolling a parser. Closes the echidna#63 "parse bridge" gap and
unblocks the OikosBot AffineScript port's webhook payload extraction
(oikos#41 + `bot-integration-affine/`).
### What lands
- **`stdlib/json.affine` v0.3** — opaque `pub extern type HpmJsonValue`
+ 11 `hpm_json_*` externs mirroring the Zig exports verbatim, plus:
- `pub fn parse(src: String) -> Option<HpmJsonValue>` (handle-returning;
caller owns + must free)
- `pub fn to_json(val: HpmJsonValue) -> Option<Json>` (tree-walk;
materialises leaves + arrays; objects descend lazily via
`hpm_json_object_get`)
- **`lib/codegen_deno.ml`** — Deno-ESM lowering: 11 entries in
`deno_builtins` mapping `hpm_json_*` → `__as_hpmJson*` JS shims (handle
== JS value; `JSON.parse` powers `hpm_json_parse`; `hpm_json_free` is a
no-op since GC reclaims).
### Object-key enumeration gap
The Zig FFI does not (yet) export an `hpm_json_object_keys` function, so
`to_json` cannot materialise objects into a full `JObject(...)` sum.
This is honest: object payloads (e.g. GitHub webhooks) descend lazily by
known key via `hpm_json_object_get` + leaf-extract — exactly how the
OikosBot port needs to use it. A follow-up PR to `hpm-json-rsr` will add
`hpm_json_object_keys` to close the round-trip.
### Verification
- ✅ `affinescript check stdlib/json.affine` — type checks
- ✅ `dune build` — clean
- ✅ `dune runtest` — same 2 pre-existing failures as `main`, no
regressions
- ✅ Runtime smoke (Deno-ESM): object descent
(`{"installation":{"id":12345}}` → `12345`), array materialisation
(`[1,2,3]` → `JArray`), malformed JSON → `None`
### Vocabulary
"Zig FFI" not "C-ABI" — the wire-level C calling convention is an
implementation detail of Zig's `export fn`. Estate convention is
Zig=FFIs / Idris2=ABIs.
## Test plan
- [ ] Type check still passes after rebase (`affinescript check
stdlib/json.affine`)
- [ ] No regression on the test suite delta
- [ ] Deno-ESM smoke driver (in PR body / follow-up test) exercises
object descent + array materialisation + malformed input
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent b95852f commit a29faa8
3 files changed
Lines changed: 176 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
209 | 209 | | |
210 | 210 | | |
211 | 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 | + | |
212 | 263 | | |
213 | 264 | | |
214 | 265 | | |
| |||
320 | 371 | | |
321 | 372 | | |
322 | 373 | | |
323 | | - | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
324 | 387 | | |
325 | 388 | | |
326 | 389 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
24 | 30 | | |
25 | 31 | | |
26 | 32 | | |
| |||
203 | 209 | | |
204 | 210 | | |
205 | 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 | + | |
206 | 312 | | |
207 | 313 | | |
208 | 314 | | |
| |||
0 commit comments