Pure OCaml xxhash implementation
1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml"><head><title>tutorial (tutorial)</title><meta charset="utf-8"/><link rel="stylesheet" href="odoc.css"/><meta name="generator" content="odoc 3.1.0"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="index.html">Up</a> – <a href="index.html">Index</a> » tutorial</nav><header class="odoc-preamble"><h1 id="yaml-tutorial"><a href="#yaml-tutorial" class="anchor"></a>YAML Tutorial</h1><p>This tutorial introduces YAML (YAML Ain't Markup Language) and demonstrates the <code>yamlrw</code> OCaml library through interactive examples. We'll start with the basics and work up to advanced features like anchors, aliases, and streaming.</p></header><div class="odoc-tocs"><nav class="odoc-toc odoc-local-toc"><ul><li><a href="#what-is-yaml?">What is YAML?</a><ul><li><a href="#yaml-vs-json">YAML vs JSON</a></li></ul></li><li><a href="#setup">Setup</a></li><li><a href="#basic-parsing">Basic Parsing</a><ul><li><a href="#boolean-values">Boolean Values</a></li><li><a href="#strings">Strings</a></li></ul></li><li><a href="#mappings-(objects)">Mappings (Objects)</a><ul><li><a href="#nested-mappings">Nested Mappings</a></li><li><a href="#accessing-values">Accessing Values</a></li></ul></li><li><a href="#sequences-(arrays)">Sequences (Arrays)</a><ul><li><a href="#sequences-of-mappings">Sequences of Mappings</a></li><li><a href="#accessing-sequence-elements">Accessing Sequence Elements</a></li></ul></li><li><a href="#serialization">Serialization</a><ul><li><a href="#constructing-values">Constructing Values</a></li><li><a href="#controlling-output-style">Controlling Output Style</a></li></ul></li><li><a href="#full-yaml-representation">Full YAML Representation</a><ul><li><a href="#scalars-with-metadata">Scalars with Metadata</a></li></ul></li><li><a href="#anchors-and-aliases">Anchors and Aliases</a><ul><li><a href="#parsing-with-aliases">Parsing with Aliases</a></li><li><a href="#preserving-aliases">Preserving Aliases</a></li></ul></li><li><a href="#multi-line-strings">Multi-line Strings</a><ul><li><a href="#literal-block-scalar">Literal Block Scalar</a></li><li><a href="#folded-block-scalar">Folded Block Scalar</a></li></ul></li><li><a href="#multiple-documents">Multiple Documents</a><ul><li><a href="#working-with-documents">Working with Documents</a></li><li><a href="#serializing-multiple-documents">Serializing Multiple Documents</a></li></ul></li><li><a href="#streaming-api">Streaming API</a><ul><li><a href="#building-yaml-with-events">Building YAML with Events</a></li></ul></li><li><a href="#error-handling">Error Handling</a><ul><li><a href="#type-errors">Type Errors</a></li></ul></li><li><a href="#common-patterns">Common Patterns</a><ul><li><a href="#configuration-files">Configuration Files</a></li><li><a href="#working-with-lists">Working with Lists</a></li><li><a href="#transforming-data">Transforming Data</a></li></ul></li><li><a href="#summary">Summary</a></li></ul></nav></div><div class="odoc-content"><h2 id="what-is-yaml?"><a href="#what-is-yaml?" class="anchor"></a>What is YAML?</h2><p>YAML is a human-readable data serialization format. It's commonly used for configuration files, data exchange, and anywhere you need structured data that humans will read and edit.</p><p>YAML is designed to be more readable than JSON or XML:</p><ul><li>No curly braces or brackets required for simple structures</li><li>Indentation defines structure (like Python)</li><li>Comments are supported</li><li>Multiple data types are recognized automatically</li></ul><h3 id="yaml-vs-json"><a href="#yaml-vs-json" class="anchor"></a>YAML vs JSON</h3><p>YAML is a superset of JSON - any valid JSON is also valid YAML. However, YAML offers additional features:</p><pre>JSON: YAML:
3{ name: Alice
4 "name": "Alice", age: 30
5 "age": 30, active: true
6 "active": true
7}</pre><p>The YAML version is cleaner for humans to read and write.</p><h2 id="setup"><a href="#setup" class="anchor"></a>Setup</h2><p>First, let's set up our environment. The library is loaded with:</p><pre class="language-ocaml"><code># open Yamlrw;;</code></pre><h2 id="basic-parsing"><a href="#basic-parsing" class="anchor"></a>Basic Parsing</h2><p>The simplest way to parse YAML is with <code>Yamlrw.of_string</code>:</p><pre class="language-ocaml"><code># let simple = of_string "hello";;
8val simple : value = `String "hello"</code></pre><p>YAML automatically recognizes different data types:</p><pre class="language-ocaml"><code># of_string "42";;
9- : value = `Float 42.
10# of_string "3.14";;
11- : value = `Float 3.14
12# of_string "true";;
13- : value = `Bool true
14# of_string "null";;
15- : value = `Null</code></pre><p>Note that integers are stored as floats in the JSON-compatible <code>Yamlrw.value</code> type, matching the behavior of JSON parsers.</p><h3 id="boolean-values"><a href="#boolean-values" class="anchor"></a>Boolean Values</h3><p>YAML recognizes many forms of boolean values:</p><pre class="language-ocaml"><code># of_string "yes";;
16- : value = `Bool true
17# of_string "no";;
18- : value = `Bool false
19# of_string "on";;
20- : value = `Bool true
21# of_string "off";;
22- : value = `Bool false</code></pre><h3 id="strings"><a href="#strings" class="anchor"></a>Strings</h3><p>Strings can be plain, single-quoted, or double-quoted:</p><pre class="language-ocaml"><code># of_string "plain text";;
23- : value = `String "plain text"
24# of_string "'single quoted'";;
25- : value = `String "single quoted"
26# of_string {|"double quoted"|};;
27- : value = `String "double quoted"</code></pre><p>Quoting is useful when your string looks like another type:</p><pre class="language-ocaml"><code># of_string "'123'";;
28- : value = `String "123"
29# of_string "'true'";;
30- : value = `String "true"</code></pre><h2 id="mappings-(objects)"><a href="#mappings-(objects)" class="anchor"></a>Mappings (Objects)</h2><p>YAML mappings associate keys with values. In the JSON-compatible representation, these become association lists:</p><pre class="language-ocaml"><code># of_string "name: Alice\nage: 30";;
31- : value = `O [("name", `String "Alice"); ("age", `Float 30.)]</code></pre><p>Keys and values are separated by a colon and space. Each key-value pair goes on its own line.</p><h3 id="nested-mappings"><a href="#nested-mappings" class="anchor"></a>Nested Mappings</h3><p>Indentation creates nested structures:</p><pre class="language-ocaml"><code># let nested = of_string {|
32database:
33 host: localhost
34 port: 5432
35 credentials:
36 user: admin
37 pass: secret
38|};;
39val nested : value =
40 `O
41 [("database",
42 `O
43 [("host", `String "localhost"); ("port", `Float 5432.);
44 ("credentials",
45 `O [("user", `String "admin"); ("pass", `String "secret")])])]</code></pre><h3 id="accessing-values"><a href="#accessing-values" class="anchor"></a>Accessing Values</h3><p>Use the <code>Yamlrw.Util</code> module to navigate and extract values:</p><pre class="language-ocaml"><code># let db = Util.get "database" nested;;
46val db : Util.t =
47 `O
48 [("host", `String "localhost"); ("port", `Float 5432.);
49 ("credentials",
50 `O [("user", `String "admin"); ("pass", `String "secret")])]
51# Util.get_string (Util.get "host" db);;
52- : string = "localhost"
53# Util.get_int (Util.get "port" db);;
54- : int = 5432</code></pre><p>For nested access, use <code>Yamlrw.Util.get_path</code>:</p><pre class="language-ocaml"><code># Util.get_path ["database"; "credentials"; "user"] nested;;
55- : Util.t option = Some (`String "admin")
56# Util.get_path_exn ["database"; "port"] nested;;
57- : Util.t = `Float 5432.</code></pre><h2 id="sequences-(arrays)"><a href="#sequences-(arrays)" class="anchor"></a>Sequences (Arrays)</h2><p>YAML sequences are written as bulleted lists:</p><pre class="language-ocaml"><code># of_string {|
58- apple
59- banana
60- cherry
61|};;
62- : value = `A [`String "apple"; `String "banana"; `String "cherry"]</code></pre><p>Or using flow style (like JSON arrays):</p><pre class="language-ocaml"><code># of_string "[1, 2, 3]";;
63- : value = `A [`Float 1.; `Float 2.; `Float 3.]</code></pre><h3 id="sequences-of-mappings"><a href="#sequences-of-mappings" class="anchor"></a>Sequences of Mappings</h3><p>A common pattern is a list of objects:</p><pre class="language-ocaml"><code># let users = of_string {|
64- name: Alice
65 role: admin
66- name: Bob
67 role: user
68|};;
69val users : value =
70 `A
71 [`O [("name", `String "Alice"); ("role", `String "admin")];
72 `O [("name", `String "Bob"); ("role", `String "user")]]</code></pre><h3 id="accessing-sequence-elements"><a href="#accessing-sequence-elements" class="anchor"></a>Accessing Sequence Elements</h3><pre class="language-ocaml"><code># Util.nth 0 users;;
73- : Util.t option =
74Some (`O [("name", `String "Alice"); ("role", `String "admin")])
75# match Util.nth 0 users with
76 | Some user -> Util.get_string (Util.get "name" user)
77 | None -> "not found";;
78- : string = "Alice"</code></pre><h2 id="serialization"><a href="#serialization" class="anchor"></a>Serialization</h2><p>Convert OCaml values back to YAML strings with <code>Yamlrw.to_string</code>:</p><pre class="language-ocaml"><code># let data = `O [
79 ("name", `String "Bob");
80 ("active", `Bool true);
81 ("score", `Float 95.5)
82 ];;
83val data :
84 [> `O of
85 (string * [> `Bool of bool | `Float of float | `String of string ])
86 list ] =
87 `O
88 [("name", `String "Bob"); ("active", `Bool true); ("score", `Float 95.5)]
89# print_string (to_string data);;
90name: Bob
91active: true
92score: 95.5
93- : unit = ()</code></pre><h3 id="constructing-values"><a href="#constructing-values" class="anchor"></a>Constructing Values</h3><p>Use <code>Yamlrw.Util</code> constructors for cleaner code:</p><pre class="language-ocaml"><code># let config = Util.obj [
94 "server", Util.obj [
95 "host", Util.string "0.0.0.0";
96 "port", Util.int 8080
97 ];
98 "debug", Util.bool true;
99 "tags", Util.strings ["api"; "v2"]
100 ];;
101val config : Value.t =
102 `O
103 [("server", `O [("host", `String "0.0.0.0"); ("port", `Float 8080.)]);
104 ("debug", `Bool true); ("tags", `A [`String "api"; `String "v2"])]
105# print_string (to_string config);;
106server:
107 host: 0.0.0.0
108 port: 8080
109debug: true
110tags:
111 - api
112 - v2
113- : unit = ()</code></pre><h3 id="controlling-output-style"><a href="#controlling-output-style" class="anchor"></a>Controlling Output Style</h3><p>You can control the output format with style options:</p><pre class="language-ocaml"><code># print_string (to_string ~layout_style:`Flow config);;
114{server: {host: 0.0.0.0, port: 8080}, debug: true, tags: [api, v2</code></pre><ul><li>: unit = ()</li></ul><p>Scalar styles control how strings are written:</p><pre class="language-ocaml"><code># print_string (to_string ~scalar_style:`Double_quoted (Util.string "hello"));;
115hello
116- : unit = ()
117# print_string (to_string ~scalar_style:`Single_quoted (Util.string "hello"));;
118hello
119- : unit = ()</code></pre><h2 id="full-yaml-representation"><a href="#full-yaml-representation" class="anchor"></a>Full YAML Representation</h2><p>The <code>Yamlrw.value</code> type is convenient but loses some YAML-specific information. For full fidelity, use the <code>Yamlrw.yaml</code> type:</p><pre class="language-ocaml"><code># let full = yaml_of_string ~resolve_aliases:false "hello";;
120val full : yaml = `Scalar <abstr></code></pre><p>The <code>Yamlrw.yaml</code> type preserves:</p><ul><li>Scalar styles (plain, quoted, literal, folded)</li><li>Anchors and aliases</li><li>Type tags</li><li>Collection styles (block vs flow)</li></ul><h3 id="scalars-with-metadata"><a href="#scalars-with-metadata" class="anchor"></a>Scalars with Metadata</h3><pre class="language-ocaml"><code># let s = yaml_of_string ~resolve_aliases:false "'quoted string'";;
121val s : yaml = `Scalar <abstr>
122# match s with
123 | `Scalar sc -> Scalar.value sc, Scalar.style sc
124 | _ -> "", `Any;;
125- : string * Scalar_style.t = ("quoted string", `Single_quoted)</code></pre><h2 id="anchors-and-aliases"><a href="#anchors-and-aliases" class="anchor"></a>Anchors and Aliases</h2><p>YAML supports node reuse through anchors (<code>&name</code>) and aliases (<code>*name</code>). This is powerful for avoiding repetition:</p><pre>defaults: &defaults
126 timeout: 30
127 retries: 3
128
129production:
130 <<: *defaults
131 host: prod.example.com
132
133staging:
134 <<: *defaults
135 host: stage.example.com</pre><h3 id="parsing-with-aliases"><a href="#parsing-with-aliases" class="anchor"></a>Parsing with Aliases</h3><p>By default, <code>Yamlrw.of_string</code> resolves aliases:</p><pre class="language-ocaml"><code># let yaml_with_alias = {|
136base: &base
137 x: 1
138 y: 2
139derived:
140 <<: *base
141 z: 3
142|};;
143val yaml_with_alias : string =
144 "\nbase: &base\n x: 1\n y: 2\nderived:\n <<: *base\n z: 3\n"
145# of_string yaml_with_alias;;
146- : value =
147`O
148 [("base", `O [("x", `Float 1.); ("y", `Float 2.)]);
149 ("derived", `O [("x", `Float 1.); ("y", `Float 2.); ("z", `Float 3.)])]</code></pre><h3 id="preserving-aliases"><a href="#preserving-aliases" class="anchor"></a>Preserving Aliases</h3><p>To preserve the alias structure, use <code>Yamlrw.yaml_of_string</code> with <code>~resolve_aliases:false</code>:</p><pre class="language-ocaml"><code># let y = yaml_of_string ~resolve_aliases:false {|
150item: &ref
151 name: shared
152copy: *ref
153|};;
154val y : yaml =
155 `O
156 <abstr></code></pre><h2 id="multi-line-strings"><a href="#multi-line-strings" class="anchor"></a>Multi-line Strings</h2><p>YAML has special syntax for multi-line strings:</p><h3 id="literal-block-scalar"><a href="#literal-block-scalar" class="anchor"></a>Literal Block Scalar</h3><p>The <code>|</code> indicator preserves newlines exactly:</p><pre class="language-ocaml"><code># of_string {|
157description: |
158 This is a
159 multi-line
160 string.
161|};;
162- : value = `O [("description", `String "This is a\nmulti-line\nstring.\n")]</code></pre><h3 id="folded-block-scalar"><a href="#folded-block-scalar" class="anchor"></a>Folded Block Scalar</h3><p>The <code>></code> indicator folds newlines into spaces:</p><pre class="language-ocaml"><code># of_string {|
163description: >
164 This is a
165 single line
166 when folded.
167|};;
168- : value = `O [("description", `String "This is a single line when folded.\n")]</code></pre><h2 id="multiple-documents"><a href="#multiple-documents" class="anchor"></a>Multiple Documents</h2><p>A YAML stream can contain multiple documents separated by <code>---</code>:</p><pre class="language-ocaml"><code># let docs = documents_of_string {|
169---
170name: first
171---
172name: second
173...
174|};;
175val docs : document list = [<abstr>; <abstr>]
176# List.length docs;;
177- : int = 2</code></pre><p>The <code>---</code> marker starts a document, and <code>...</code> optionally ends it.</p><h3 id="working-with-documents"><a href="#working-with-documents" class="anchor"></a>Working with Documents</h3><p>Each document has metadata and a root value:</p><pre class="language-ocaml"><code># List.map (fun d -> Document.root d) docs;;
178- : Yaml.t option list =
179[Some (`O <abstr>); Some (`O <abstr>)]</code></pre><h3 id="serializing-multiple-documents"><a href="#serializing-multiple-documents" class="anchor"></a>Serializing Multiple Documents</h3><pre class="language-ocaml"><code># let doc1 = Document.make (Some (of_json (Util.obj ["x", Util.int 1])));;
180val doc1 : Document.t =
181 {Document.version = None; tags = []; root = Some (`O <abstr>);
182 implicit_start = true; implicit_end = true}
183# let doc2 = Document.make (Some (of_json (Util.obj ["x", Util.int 2])));;
184val doc2 : Document.t =
185 {Document.version = None; tags = []; root = Some (`O <abstr>);
186 implicit_start = true; implicit_end = true}
187# print_string (documents_to_string [doc1; doc2]);;
188x: 1
189---
190x: 2
191- : unit = ()</code></pre><h2 id="streaming-api"><a href="#streaming-api" class="anchor"></a>Streaming API</h2><p>For large files or fine-grained control, use the streaming API:</p><pre class="language-ocaml"><code># let parser = Stream.parser "key: value";;
192val parser : Stream.parser = <abstr></code></pre><p>Iterate over events:</p><pre class="language-ocaml"><code># Stream.iter (fun event _ _ ->
193 Format.printf "%a@." Event.pp event
194 ) parser;;
195stream-start(UTF-8)
196document-start(version=none, implicit=true)
197mapping-start(anchor=none, tag=none, implicit=true, style=block)
198scalar(anchor=none, tag=none, style=plain, value="key")
199scalar(anchor=none, tag=none, style=plain, value="value")
200mapping-end
201document-end(implicit=true)
202stream-end
203- : unit = ()</code></pre><h3 id="building-yaml-with-events"><a href="#building-yaml-with-events" class="anchor"></a>Building YAML with Events</h3><p>You can also emit YAML by sending events:</p><pre class="language-ocaml"><code># let emitter = Stream.emitter ();;
204val emitter : Stream.emitter = <abstr>
205# Stream.stream_start emitter `Utf8;;
206- : unit = ()
207# Stream.document_start emitter ();;
208- : unit = ()
209# Stream.mapping_start emitter ();;
210- : unit = ()
211# Stream.scalar emitter "greeting";;
212- : unit = ()
213# Stream.scalar emitter "Hello, World!";;
214- : unit = ()
215# Stream.mapping_end emitter;;
216- : unit = ()
217# Stream.document_end emitter ();;
218- : unit = ()
219# Stream.stream_end emitter;;
220- : unit = ()
221# print_string (Stream.contents emitter);;
222greeting: Hello, World!
223- : unit = ()</code></pre><h2 id="error-handling"><a href="#error-handling" class="anchor"></a>Error Handling</h2><p>Parse errors raise <code>Yamlrw.Yamlrw_error</code>:</p><pre class="language-ocaml"><code># try
224 ignore (of_string "key: [unclosed");
225 "ok"
226 with Yamlrw_error e ->
227 Error.to_string e;;
228- : string = "expected sequence end ']' at line 1, columns 15-15"</code></pre><h3 id="type-errors"><a href="#type-errors" class="anchor"></a>Type Errors</h3><p>The <code>Yamlrw.Util</code> module raises <code>Yamlrw.Util.Type_error</code> for type mismatches:</p><pre class="language-ocaml"><code># try
229 ignore (Util.get_string (`Float 42.));
230 "ok"
231 with Util.Type_error (expected, actual) ->
232 Printf.sprintf "expected %s, got %s" expected (Value.type_name actual);;
233- : string = "expected string, got float"</code></pre><h2 id="common-patterns"><a href="#common-patterns" class="anchor"></a>Common Patterns</h2><h3 id="configuration-files"><a href="#configuration-files" class="anchor"></a>Configuration Files</h3><p>A typical configuration file pattern:</p><pre class="language-ocaml"><code># let config_yaml = {|
234app:
235 name: myapp
236 version: 1.0.0
237
238server:
239 host: 0.0.0.0
240 port: 8080
241 ssl: true
242
243database:
244 url: postgres://localhost/mydb
245 pool_size: 10
246|};;
247val config_yaml : string =
248 "app:\n name: myapp\n version: 1.0.0\n\nserver:\n host: 0.0.0.0\n port: 8080\n ssl: true\n\ndatabase:\n url: postgres://localhost/mydb\n pool_size: 10\n"
249# let config = of_string config_yaml;;
250val config : value =
251 `O
252 [("app", `O [("name", `String "myapp"); ("version", `Float 1.)]);
253 ("server",
254 `O
255 [("host", `String "0.0.0.0"); ("port", `Float 8080.);
256 ("ssl", `Bool true)]);
257 ("database",
258 `O
259 [("url", `String "postgres://localhost/mydb");
260 ("pool_size", `Float 10.)])]
261# let server = Util.get "server" config;;
262val server : Util.t =
263 `O
264 [("host", `String "0.0.0.0"); ("port", `Float 8080.); ("ssl", `Bool true)]
265# let host = Util.to_string ~default:"localhost" (Util.get "host" server);;
266val host : string = "0.0.0.0"
267# let port = Util.to_int ~default:80 (Util.get "port" server);;
268val port : int = 8080</code></pre><h3 id="working-with-lists"><a href="#working-with-lists" class="anchor"></a>Working with Lists</h3><p>Processing lists of items:</p><pre class="language-ocaml"><code># let items_yaml = {|
269items:
270 - id: 1
271 name: Widget
272 price: 9.99
273 - id: 2
274 name: Gadget
275 price: 19.99
276 - id: 3
277 name: Gizmo
278 price: 29.99
279|};;
280val items_yaml : string =
281 "items:\n - id: 1\n name: Widget\n price: 9.99\n - id: 2\n name: Gadget\n price: 19.99\n - id: 3\n name: Gizmo\n price: 29.99\n"
282# let items = Util.get_list (Util.get "items" (of_string items_yaml));;
283val items : Util.t list =
284 [`O [("id", `Float 1.); ("name", `String "Widget"); ("price", `Float 9.99)];
285 `O [("id", `Float 2.); ("name", `String "Gadget"); ("price", `Float 19.99)];
286 `O [("id", `Float 3.); ("name", `String "Gizmo"); ("price", `Float 29.99)]]
287# let names = List.map (fun item ->
288 Util.get_string (Util.get "name" item)
289 ) items;;
290val names : string list = ["Widget"; "Gadget"; "Gizmo"]
291# let total = List.fold_left (fun acc item ->
292 acc +. Util.get_float (Util.get "price" item)
293 ) 0. items;;
294val total : float = 59.97</code></pre><h3 id="transforming-data"><a href="#transforming-data" class="anchor"></a>Transforming Data</h3><p>Modifying YAML structures:</p><pre class="language-ocaml"><code># let original = of_string "name: Alice\nstatus: active";;
295val original : value =
296 `O [("name", `String "Alice"); ("status", `String "active")]
297# let updated = Util.update "status" (Util.string "inactive") original;;
298val updated : Value.t =
299 `O [("name", `String "Alice"); ("status", `String "inactive")]
300# let with_timestamp = Util.update "updated_at" (Util.string "2024-01-01") updated;;
301val with_timestamp : Value.t =
302 `O
303 [("name", `String "Alice"); ("status", `String "inactive");
304 ("updated_at", `String "2024-01-01")]
305# print_string (to_string with_timestamp);;
306name: Alice
307status: inactive
308updated_at: 2024-01-01
309- : unit = ()</code></pre><h2 id="summary"><a href="#summary" class="anchor"></a>Summary</h2><p>The <code>yamlrw</code> library provides:</p><ol><li><b>Simple parsing</b>: <code>Yamlrw.of_string</code> for JSON-compatible values</li><li><b>Full fidelity</b>: <code>Yamlrw.yaml_of_string</code> preserves all YAML metadata</li><li><b>Easy serialization</b>: <code>Yamlrw.to_string</code> with style options</li><li><b>Navigation</b>: <code>Yamlrw.Util</code> module for accessing and modifying values</li><li><b>Multi-document</b>: <code>Yamlrw.documents_of_string</code> for YAML streams</li><li><b>Streaming</b>: <code>Yamlrw.Stream</code> module for event-based processing</li></ol><p>Key types:</p><ul><li><code>Yamlrw.value</code> - JSON-compatible representation (<code>`Null</code>, <code>`Bool</code>, <code>`Float</code>, <code>`String</code>, <code>`A</code>, <code>`O</code>)</li><li><code>Yamlrw.yaml</code> - Full YAML with scalars, anchors, aliases, and metadata</li><li><code>Yamlrw.document</code> - A complete document with directives</li></ul><p>For more details, see the <span class="xref-unresolved" title="Yamlrw">API reference</span>.</p></div></body></html>