Formats: TOML, JSON, YAML
Reading
The three parsers are string methods, and they return ordinary Aura objects and lists:
cargo = read_file("./Cargo.toml").parse_toml()
team = read_file("./team.json").parse_json()
lint = read_file("./.rules.yaml").parse_yaml()
service:
name: cargo.package.name
owner: team.teams[0].lead
end
Integers from every format arrive as Int, with no loss of precision. A parse
failure is E0314, carrying the underlying library’s message.
Writing
From the CLI, with a flag:
aura eval app.aura --format json # the default, pretty-printed
aura eval app.aura --format json-flat # flattened keys: a.b.c = 1
aura eval app.aura --format yaml
aura eval app.aura --format toml # requires an object at the top level
From inside the language, with methods. Each format has two of them, and the choice is about who reads the result:
configmap:
# Read by a program: the compact form, because the newlines would only be
# escaped on the way in.
"app-config.yaml": settings.to_yaml()
# Read by a person, in `kubectl get cm -o yaml` or in a diff: spelled out.
"reference.yaml": settings.to_yaml_pretty()
end
to_json / to_yaml / to_toml give the most compact form the format allows;
to_json_pretty / to_yaml_pretty / to_toml_pretty give the form a person
reads. Compact YAML is flow style — {a: 1, xs: [1, 2]} — which is ordinary
YAML, not a dialect. Compact TOML keeps arrays on one line.
The CLI is the other way round: --format always writes the spelled-out form,
because it is producing a document rather than a string that goes inside one.
TOML’s limitations become honest E0603 errors: it has no null, and it requires
an object at the top level.
json-flat joins nested keys with a dot, which stays unambiguous only while no key
contains one. Keys written in Aura are identifiers, so they cannot — but
parse_json and friends return whatever the input held, and then {"a": {"b": 1}}
and {"a.b": 2} both want the key a.b. That is E0604 rather than one value
quietly overwriting the other. An empty object flattens to itself (a.b: {}); it is
a leaf, exactly as an empty list is.
Aura as a converter
Because the language reads and writes all three formats, a migration is one line:
# convert.aura
config: read_file("./legacy.toml").parse_toml()
aura eval convert.aura --allow-read=. --format yaml
Unlike yq or jq, schemas, assert and merging several sources are available
along the way — conversion with guarantees.