diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-11 13:05:31 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-08-11 13:05:31 +0200 |
| commit | 03d414cb1847fa4bdf4b9d521d6d2c0a47766113 (patch) | |
| tree | 6d43866f3485294c5498878ff77abe22ab81946d /lib | |
| parent | 5046defebb8e04d00489a6be070b1b7e7a49ce84 (diff) | |
| download | colitur-03d414cb1847fa4bdf4b9d521d6d2c0a47766113.tar.gz colitur-03d414cb1847fa4bdf4b9d521d6d2c0a47766113.zip | |
fix(record): derive headers and to_row from a single columns list
Make alignment impossible: both headers and to_row are derived from a single
list of (name, extractor) pairs, so reordering one without the other is
impossible. CSV schema cannot silently mislabel columns.
Add a meaningful test that pins the header names in order, not just length.
This catches column reordering regressions.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/kernel/record.ml | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/lib/kernel/record.ml b/lib/kernel/record.ml index af55f07..425aad5 100644 --- a/lib/kernel/record.ml +++ b/lib/kernel/record.ml @@ -33,8 +33,21 @@ let of_temporal ~rite vocab date (t : ('s, 'r) Temporal.t) = cel.Celebration.citations; } -let headers = - [ "date"; "rite"; "season"; "week"; "weekday"; "slug"; "rank"; "colour"; "subject" ] +(* Scalar columns, each with a (name, extractor) pair. Derived from this single + source ensures headers and to_row cannot drift apart. Names and citations are + excluded: they are variable-arity and belong to richer encoders in Plan 5. *) +let columns = + [ ("date", fun r -> r.date); + ("rite", fun r -> r.rite); + ("season", fun r -> r.season); + ("week", fun r -> r.week); + ("weekday", fun r -> r.weekday); + ("slug", fun r -> r.slug); + ("rank", fun r -> r.rank); + ("colour", fun r -> r.colour); + ("subject", fun r -> r.subject); + ] -let to_row r = - [ r.date; r.rite; r.season; r.week; r.weekday; r.slug; r.rank; r.colour; r.subject ] +let headers = List.map fst columns + +let to_row r = List.map (fun (_, get) -> get r) columns |
