YAML 1.0, 1.1 and 1.2 for MoonBit.
test {
let config = @moonyaml.loads(
#|server:
#| host: 0.0.0.0
#| port: 12000
#|limits: &shared { files: 1000, bytes: 1048576 }
#|upload: *shared
)
println(@moonyaml.dumps(config)) // back to YAML, block style
}test {
let doc = @moonyaml.parse(
#|# the deployment
#|name: web
#|ports: [80, 443]
)
println(@moonyaml.emit(doc)) // the same document, comment and all
println(doc.to_json().stringify()) // what it means
}moon add moonbitstack/moonyaml| Package | What it is |
|---|---|
| moonbitstack/moonyaml | YAML 1.2.2's core schema, the writer, the document model, and the typed codec |
| moonbitstack/moonyaml/yaml11 | YAML 1.1: yes/no/on/off as booleans, 014 as octal, sexagesimals, 1_000, and the << merge key |
| moonbitstack/moonyaml/yaml10 | YAML 1.0's types, which 1.1 inherited but did not always keep |
| moonbitstack/moonyaml/strict | The strict dialect: block structure only, every scalar a string, no flow style, no anchors, no tags, no repeated keys |
| moonbitstack/moonyaml/any | Reads the version a document asks for with %YAML, and 1.2.2 when it asks for nothing |
| Function | Gives back |
|---|---|
| loads(src) / loads_all(src) | Json — the one document, or every document in the stream |
| load(bytes) / load_all(bytes) | The same, decoding UTF-8 and skipping a leading BOM |
| loads_as[T](src) / load_as[T](bytes) | A typed value, through @json.FromJson |
| dumps(value) / dumps_all(values) | YAML text |
| dump(value) / dump_all(values) | The same, as Bytes |
| dumps_of[T](value) / dumps_of_all[T](values) | The same, through @json.ToJson |
| round_trip[T](src, adjust~) | A typed value written back, for checking that a decode is a decode |
| parse(src) / parse_all(src) | Node — the document, comments and all |
| emit(node) | YAML text that reads back as the same document |
| events_all(nodes) / node.events() | The parse, as the event stream a reader would report |
| declared_version(src) | The %YAML a document asks for, or None |
| Collections | Block mappings and sequences, flow {} and [], nested in either direction, a sequence in its parent key's own column, a collection as a key |
| Scalars | Plain over several lines (breaks fold, blank lines do not), single- and double-quoted with the escapes of §5.7, literal \| and folded > with chomping and explicit indentation |
| Structure | Anchors and aliases, tags including %TAG handles and verbatim !<…>, %YAML, --- and ... markers, ? key explicit pairs, complex keys |
| Resolution | The core schema of §10.2: null/~, booleans, decimal, 0o and 0x integers, floats with exponents, .inf and .nan |
test {
let doc = @moonyaml.parse(
#|# the deployment
#|name: web
#|ports: [80, 443]
#|motd: |
#| one
#| two
)
match doc.kind {
Mapping(pairs) => println(pairs[2].0.text) // ports
_ => ()
}
println(@moonyaml.emit(doc)) // the same file, comment and all
}+STR
+DOC
+MAP
=VAL :name
=VAL :web
-MAP
-DOC
-STR@moonyaml.loads(src, flavor=@moonyaml.Flavor::new(duplicates=Reject))
@moonyaml.loads(src, flavor={ ..@moonyaml.strict, budget: 1000 })
@moonyaml.dumps(value, style=@moonyaml.flow)
@moonyaml.dumps(value, indent=4, sort=true)| Flavor | Preset | Why that value |
|---|---|---|
| depth | 500 | Deeper than any configuration file nests, shallow enough that the reader's own recursion cannot be driven off the stack |
| duplicates | Last | A mapping names each key once (§3.2.1.1); where one is written twice, the last is the one the document ends with. First and Reject are there because a repeated key is usually a mistake |
| aliases | true | An alias is part of the language; false refuses one outright |
| budget | 10 000 000 | Nodes one document's aliases may expand to. A dozen lines of aliases can name billions of nodes, so the expansion is counted and capped rather than performed |
| Style | Preset | Why that value |
|---|---|---|
| indent | 2 | Two columns per level, which is what a hand-written configuration file uses and what fits a diff |
| width | 80 | Where a collection stops fitting on a line and Auto breaks it |
| layout | Block | Block style reads better in a diff; Flow writes JSON's own shape, Auto decides per collection by width |
| quotes | Minimal | Quote only what has to be quoted, which is what a person writing YAML does |
| anchors | true | A collection that appears twice is written once and referenced |
| sort | false | A document keeps the order it was written in; a caller who wants a stable file turns this on |
a: [1, 2 => 1:4: ends mid-document
a: *nope => 1:4: no anchor named `nope`
a: 1, a: 2 => 2:1: the key `a` is written twicemoon run src/examples/tour # everything it reads, in one file
moon run src/examples/versions # one document, read five ways
moon run src/examples/document # the document model, and a round trippub(all) struct Flavor {
depth : Int
duplicates : Duplicates
aliases : Bool
budget : Int
} derive(Eq, Debug)pub(all) struct Node {
kind : Kind
text : String
style : ScalarStyle
flow : Bool
anchor : String?
tag : String?
before : Array[String]
after : String?
explicit : Bool
closed : Bool
}let budget : Intfn declared_version(src : StringView) -> (Int, Int)?let depth : Intlet indent : Intlet config : Config = @moonyaml.loads_as(src)let width : Int