Alpha. Vary is under active development and not ready for production use. Syntax, APIs, performance, and behaviour may change between releases.
mapping
import mapping covers the one-line list-to-list translations that turn
typed query rows into contract values or JSON arrays. The intent is to
keep the row-to-response loop out of handlers so the response shape stays
in one place: the json ... from ... mapping declaration.
Mapping typed rows
import mapping
let summaries = mapping.map_rows(rows, lambda row: IssueRow: issue_summary(row))
map_rows[Row, Out](rows, mapper) returns a List[Out] with one entry
per input row. The contract assertion is "same length"; the mapper is
expected to be total.
Mapping to JSON arrays
import mapping
let issues_json = mapping.json_array_map(rows, lambda row: IssueRow: row_to_json(row))
return api_response.ok_array("issues", issues_json)
| Helper | Purpose |
|---|---|
json_array_map(rows, mapper) | Maps to a Json array of objects. |
json_string_array_map(rows, mapper) | Maps to a Json array of strings. |
json_object_fields(fields, values) | Json object from parallel key and value lists. |
json_parse_or_empty_object(text) | Empty object on parse failure (tolerant decode). |
json_parse_or_empty_array(text) | Returns an empty array on parse failure. |
Interaction with json ... from ...
The DSL form is preferred when the row-to-response shape is stable:
json issue_summary from IssueRow as row projected by public_field_policy {
id: row.id
title: row.title
severity: row.severity
}
Reach for mapping in these situations:
| Situation | Why the declarative form does not fit |
|---|---|
| Cross-row aggregation instead of per-row projection | json ... projected by ... is row-local. |
Gluing typed rows into api_response.ok_array | The envelope wants a List; mapping builds it. |
| Migrating from hand-rolled loops | Bridge until shapes live in a json declaration. |
ManualRowMappingRule and ManualResponseEnvelopeRule are the check
rules that point new code at this module.