@zio.dev/zio-blocks 0.0.33 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/guides/compile-time-resource-safety-with-scope.md +16 -17
- package/guides/getting-started-with-mux.md +1507 -0
- package/guides/query-dsl-extending.md +161 -102
- package/guides/query-dsl-fluent-builder.md +217 -157
- package/guides/query-dsl-reified-optics.md +12 -10
- package/guides/query-dsl-sql.md +246 -165
- package/guides/telemetry-guide.md +1069 -0
- package/guides/zio-schema-migration.md +29 -22
- package/index.md +292 -50
- package/package.json +1 -1
- package/plans/config-follow-up-prs.md +188 -0
- package/plans/config-pr-assessment-roadmap.md +310 -0
- package/reference/MuxDataFlow.jsx +250 -0
- package/reference/async.md +651 -0
- package/reference/chunk.md +3533 -308
- package/reference/codegen/case-class.md +436 -0
- package/reference/codegen/emitter-config.md +383 -0
- package/reference/codegen/examples.md +664 -0
- package/reference/codegen/field.md +316 -0
- package/reference/codegen/index.md +317 -0
- package/reference/codegen/scala-emitter.md +392 -0
- package/reference/codegen/scala-file.md +276 -0
- package/reference/codegen/sealed-trait.md +408 -0
- package/reference/codegen/type-definition.md +340 -0
- package/reference/codegen/type-ref.md +201 -0
- package/reference/combinators.md +347 -117
- package/reference/config.md +158 -0
- package/reference/context.md +4 -4
- package/reference/datastar.md +346 -0
- package/reference/docs.md +1461 -345
- package/reference/endpoint/auth-type.md +146 -0
- package/reference/endpoint/endpoint.md +297 -0
- package/reference/endpoint/http-codec.md +249 -0
- package/reference/endpoint/index.md +825 -0
- package/reference/endpoint/path-codec.md +237 -0
- package/reference/endpoint/route-pattern.md +196 -0
- package/reference/endpoint/route-tree.md +111 -0
- package/reference/endpoint/segment-codec.md +212 -0
- package/reference/html.md +1120 -0
- package/reference/htmx/attribute-values.md +359 -0
- package/reference/htmx/hx-encoding.md +111 -0
- package/reference/htmx/hx-params.md +204 -0
- package/reference/htmx/hx-swap.md +276 -0
- package/reference/htmx/hx-sync.md +251 -0
- package/reference/htmx/hx-target.md +314 -0
- package/reference/htmx/hx-trigger.md +457 -0
- package/reference/htmx/hx-url-update.md +239 -0
- package/reference/htmx/index.md +855 -0
- package/reference/http-model/index.md +47 -0
- package/reference/http-model/model.md +1481 -0
- package/reference/http-model/schema.md +747 -0
- package/reference/maybe.md +826 -0
- package/reference/media-type.md +2 -2
- package/reference/mux.mdx +823 -0
- package/reference/openapi.md +1351 -0
- package/reference/resource-management/defer-handle.md +1 -1
- package/reference/resource-management/resource.md +31 -2
- package/reference/resource-management/scope.md +28 -12
- package/reference/resource-management/wire.md +3 -7
- package/reference/ringbuffer/MpmcDiagram.jsx +717 -0
- package/reference/ringbuffer/MpscDiagram.jsx +618 -0
- package/reference/ringbuffer/SpmcDiagram.jsx +680 -0
- package/reference/ringbuffer/SpscDiagram.jsx +677 -0
- package/reference/ringbuffer/advanced.mdx +109 -0
- package/reference/ringbuffer/index.mdx +145 -0
- package/reference/ringbuffer/mpmc.mdx +151 -0
- package/reference/ringbuffer/mpsc.mdx +132 -0
- package/reference/ringbuffer/spmc.mdx +108 -0
- package/reference/ringbuffer/spsc.mdx +344 -0
- package/reference/{allows.md → schema/allows.md} +4 -4
- package/reference/{binding-resolver.md → schema/binding-resolver.md} +1 -1
- package/reference/{binding.md → schema/binding.md} +2 -3
- package/reference/schema/built-in-codecs/avro.md +451 -0
- package/reference/schema/built-in-codecs/bson.md +480 -0
- package/reference/schema/built-in-codecs/csv.md +564 -0
- package/reference/schema/built-in-codecs/index.md +77 -0
- package/reference/schema/built-in-codecs/json/index.md +295 -0
- package/reference/schema/built-in-codecs/json/json-config.md +217 -0
- package/reference/{json-patch.md → schema/built-in-codecs/json/json-patch.md} +5 -5
- package/reference/{json-schema.md → schema/built-in-codecs/json/json-schema.md} +14 -47
- package/reference/schema/built-in-codecs/json/json-selection.md +322 -0
- package/reference/{json.md → schema/built-in-codecs/json/json.md} +32 -64
- package/reference/schema/built-in-codecs/messagepack.md +508 -0
- package/reference/schema/built-in-codecs/thrift.md +433 -0
- package/reference/schema/built-in-codecs/toon.md +1078 -0
- package/reference/{xml.md → schema/built-in-codecs/xml.md} +13 -9
- package/reference/schema/built-in-codecs/yaml.md +552 -0
- package/reference/{codec.md → schema/codec.md} +10 -10
- package/reference/{dynamic-optic.md → schema/dynamic-optic.md} +151 -5
- package/reference/{dynamic-schema.md → schema/dynamic-schema.md} +8 -8
- package/reference/schema/format.md +92 -0
- package/reference/schema/index.md +50 -0
- package/reference/schema/migration.md +297 -0
- package/reference/{modifier.md → schema/modifier.md} +58 -7
- package/reference/{optics.md → schema/optics.md} +2 -2
- package/reference/{patch.md → schema/patch.md} +1 -1
- package/{path-interpolator.md → reference/schema/path-interpolator.md} +165 -72
- package/reference/{schema-evolution → schema/schema-evolution}/as.md +8 -8
- package/reference/{schema-evolution → schema/schema-evolution}/index.md +2 -2
- package/reference/{schema-evolution → schema/schema-evolution}/into.md +8 -8
- package/reference/{schema-expr.md → schema/schema-expr.md} +110 -175
- package/reference/{schema.md → schema/schema.md} +12 -0
- package/reference/{structural-types.md → schema/structural-types.md} +1 -1
- package/reference/{type-class-derivation.md → schema/type-class-derivation.md} +63 -1
- package/reference/smithy.md +533 -0
- package/reference/sql/db-codec-deriver.md +71 -0
- package/reference/sql/db-codec.md +687 -0
- package/reference/sql/db-con.md +271 -0
- package/reference/sql/db-connection.md +153 -0
- package/reference/sql/db-param-writer.md +77 -0
- package/reference/sql/db-param.md +66 -0
- package/reference/sql/db-result-reader.md +146 -0
- package/reference/sql/db-tx.md +82 -0
- package/reference/sql/db-value.md +41 -0
- package/reference/sql/ddl.md +85 -0
- package/reference/sql/frag.md +254 -0
- package/reference/sql/index.md +341 -0
- package/reference/sql/repo.md +600 -0
- package/reference/sql/sql-dialect.md +73 -0
- package/reference/sql/sql-logger.md +62 -0
- package/reference/sql/sql-name-mapper.md +70 -0
- package/reference/sql/table-metadata.md +134 -0
- package/reference/sql/table.md +448 -0
- package/reference/sql/transactor-zio.md +399 -0
- package/reference/sql/transactor.md +353 -0
- package/reference/sql-zio.md +112 -0
- package/reference/streams/concurrent-operators.md +106 -0
- package/reference/streams/index.md +653 -0
- package/reference/streams/pipeline.md +718 -0
- package/reference/streams/reader.md +1284 -0
- package/reference/streams/scala-2-compatibility.md +55 -0
- package/reference/streams/sink.md +1426 -0
- package/reference/streams/stream.md +2526 -0
- package/reference/streams/writer.md +1045 -0
- package/reference/streams/zero-boxing.md +275 -0
- package/reference/telemetry.md +693 -0
- package/reference/typeid.md +5 -19
- package/sidebars.js +238 -43
- package/reference/formats.md +0 -694
- package/reference/http-model.md +0 -1716
- package/reference/streams.md +0 -989
- package/ringbuffer.md +0 -249
- /package/reference/{json-differ.md → schema/built-in-codecs/json/json-differ.md} +0 -0
- /package/reference/{dynamic-value.md → schema/dynamic-value.md} +0 -0
- /package/reference/{lazy.md → schema/lazy.md} +0 -0
- /package/reference/{reflect.md → schema/reflect.md} +0 -0
- /package/reference/{registers.md → schema/registers.md} +0 -0
- /package/reference/{schema-error.md → schema/schema-error.md} +0 -0
- /package/reference/{syntax.md → schema/syntax.md} +0 -0
- /package/reference/{validation.md → schema/validation.md} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: xml
|
|
3
|
-
title: "XML"
|
|
3
|
+
title: "XML Codec Module"
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
`Xml` is a **sealed trait representing XML nodes**. It provides a type-safe, immutable representation of all valid XML document structures including elements, text nodes, CDATA sections, comments, and processing instructions.
|
|
@@ -303,7 +303,7 @@ Use `WriterConfig` to control XML output formatting:
|
|
|
303
303
|
import zio.blocks.schema.xml.WriterConfig
|
|
304
304
|
|
|
305
305
|
// Compact output (default)
|
|
306
|
-
val compact = WriterConfig
|
|
306
|
+
val compact = WriterConfig
|
|
307
307
|
// <Person><name>Alice</name></Person>
|
|
308
308
|
|
|
309
309
|
// Pretty-printed with 2-space indentation
|
|
@@ -520,7 +520,8 @@ Filter selections by node type or custom predicates:
|
|
|
520
520
|
```scala
|
|
521
521
|
import zio.blocks.schema.xml._
|
|
522
522
|
|
|
523
|
-
val
|
|
523
|
+
val xml = XmlReader.read("<root><item>text1</item><comment>note</comment></root>")
|
|
524
|
+
val selection = xml.select.descendant("item")
|
|
524
525
|
|
|
525
526
|
// Filter by type
|
|
526
527
|
val elements = selection.elements
|
|
@@ -538,7 +539,8 @@ Execute a selection to extract values or convert to other formats:
|
|
|
538
539
|
```scala
|
|
539
540
|
import zio.blocks.schema.xml._
|
|
540
541
|
|
|
541
|
-
val
|
|
542
|
+
val xml = XmlReader.read("<root><item>A</item><item>B</item></root>")
|
|
543
|
+
val selection = xml.select.get("item")
|
|
542
544
|
|
|
543
545
|
// Get single value (fails if not exactly one)
|
|
544
546
|
val one: Either[SchemaError, Xml] = selection.one
|
|
@@ -564,8 +566,10 @@ Combine and transform selections using monadic operations:
|
|
|
564
566
|
```scala
|
|
565
567
|
import zio.blocks.schema.xml._
|
|
566
568
|
|
|
567
|
-
val
|
|
568
|
-
val
|
|
569
|
+
val xml1 = XmlReader.read("<root><item>X</item></root>")
|
|
570
|
+
val xml2 = XmlReader.read("<root><item>Y</item></root>")
|
|
571
|
+
val selection1 = xml1.select.get("item")
|
|
572
|
+
val selection2 = xml2.select.get("item")
|
|
569
573
|
|
|
570
574
|
// Map over selections
|
|
571
575
|
val mapped = selection1.map(xml => xml)
|
|
@@ -638,7 +642,7 @@ Apply a patch to an XML document to produce a modified result:
|
|
|
638
642
|
import zio.blocks.schema._
|
|
639
643
|
import zio.blocks.schema.xml._
|
|
640
644
|
|
|
641
|
-
val xml
|
|
645
|
+
val xml = XmlReader.read("<person><name>Alice</name></person>")
|
|
642
646
|
val patch = XmlPatch.setAttribute(p".person", "active", "true")
|
|
643
647
|
|
|
644
648
|
// Apply the patch
|
|
@@ -793,8 +797,8 @@ object Person {
|
|
|
793
797
|
implicit val schema: Schema[Person] = Schema.derived
|
|
794
798
|
}
|
|
795
799
|
|
|
796
|
-
// Get the underlying
|
|
797
|
-
val codec: XmlCodec[Person] = Schema[Person].derive(
|
|
800
|
+
// Get the underlying XML codec
|
|
801
|
+
val codec: XmlCodec[Person] = Schema[Person].derive(XmlFormat)
|
|
798
802
|
|
|
799
803
|
// Encode to Xml directly
|
|
800
804
|
val person = Person("Alice", 30)
|
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: yaml
|
|
3
|
+
title: "YAML Codec Module"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`zio-blocks-schema-yaml` is a **schema-driven YAML codec module** for serializing and deserializing Scala types to and from YAML format. It provides comprehensive encoding and decoding with support for 27 primitive types, records, variants, sequences, maps, and recursive types. Core types: `Yaml`, `YamlCodec`, `YamlCodecDeriver`, `YamlOptions`.
|
|
7
|
+
|
|
8
|
+
The module integrates with a pure-Scala YAML parser and writer to provide human-readable serialization with optional JSON interoperability, configuration options for pretty-printing, and automatic schema generation.
|
|
9
|
+
|
|
10
|
+
## Motivation
|
|
11
|
+
|
|
12
|
+
YAML is a human-readable data format that appears widely across configuration files, Kubernetes manifests, CI/CD pipelines, and data serialization. Manually writing YAML encoders and decoders is error-prone and repetitive, especially for complex types with records, nested structures, and recursive definitions. `zio-blocks-schema-yaml` eliminates this friction by deriving codec instances directly from your Scala types using ZIO Schema. You describe your data shape once, and the module handles:
|
|
13
|
+
- Full YAML type support (mappings, sequences, scalars, null)
|
|
14
|
+
- Automatic schema generation from Scala types
|
|
15
|
+
- Pretty-printed and compact formatting options
|
|
16
|
+
- JSON interoperability for seamless conversion
|
|
17
|
+
- Precise error reporting with location traces showing the path to errors
|
|
18
|
+
- Recursive type support with automatic cycle detection
|
|
19
|
+
- Multiple encoding paths: byte arrays and strings
|
|
20
|
+
- Multiple decoding paths: byte arrays and strings
|
|
21
|
+
- Cross-platform compatibility (JVM and Scala.js)
|
|
22
|
+
|
|
23
|
+
Rather than hand-writing YAML parsing logic or relying on external libraries with limited Scala support, you work with strongly-typed schemas that the compiler validates.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Add the module to your `build.sbt`:
|
|
28
|
+
|
|
29
|
+
```sbt
|
|
30
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-yaml" % "0.0.51"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For Scala.js, use `%%%` instead of `%%`:
|
|
34
|
+
|
|
35
|
+
```sbt
|
|
36
|
+
libraryDependencies += "dev.zio" %%% "zio-blocks-schema-yaml" % "0.0.51"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Supported Scala versions: 2.13.x and 3.x
|
|
40
|
+
|
|
41
|
+
## Introduction
|
|
42
|
+
|
|
43
|
+
The module provides a complete pipeline for YAML codec derivation and usage:
|
|
44
|
+
|
|
45
|
+
1. **Define your type** — Any Scala type with a `Schema` instance
|
|
46
|
+
2. **Derive a codec** — Use `Schema[A].derive(YamlFormat)` to obtain a `YamlCodec[A]`
|
|
47
|
+
3. **Encode or decode** — Call `codec.encodeToString(value)` or `codec.decode(yamlString)`
|
|
48
|
+
4. **Handle errors** — Catch `SchemaError` with location traces showing where the error occurred
|
|
49
|
+
5. **Configure output** — Use `YamlOptions` for pretty-printing or compact formatting
|
|
50
|
+
|
|
51
|
+
The derivation process is automatic for all supported types (all 27 primitives, records, variants, sequences, maps). The module automatically generates YAML-compatible formats and handles encoding/decoding without manual configuration.
|
|
52
|
+
|
|
53
|
+
## How They Work Together
|
|
54
|
+
|
|
55
|
+
The YAML codec pipeline flows through these layers:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
1. User defines Schema[A] for their type
|
|
59
|
+
↓
|
|
60
|
+
2. Schema[A].derive(YamlFormat) creates YamlCodec[A]
|
|
61
|
+
↓
|
|
62
|
+
3. YamlCodecDeriver derives Encoder and Decoder implementations
|
|
63
|
+
- For primitives: type-specific YAML scalar encoders/decoders
|
|
64
|
+
- For records: field-by-field composition with YAML mapping
|
|
65
|
+
- For variants: union encoding with discriminators
|
|
66
|
+
- For sequences: YAML sequence encoding/decoding
|
|
67
|
+
- For maps: YAML mapping encoding/decoding
|
|
68
|
+
↓
|
|
69
|
+
4. YamlCodec provides multiple encoding paths
|
|
70
|
+
- encodeToString(value) → String
|
|
71
|
+
- encode(value) → Array[Byte]
|
|
72
|
+
↓
|
|
73
|
+
5. YamlCodec provides multiple decoding paths
|
|
74
|
+
- decode(yaml: String) → Either[SchemaError, A]
|
|
75
|
+
- decode(bytes: Array[Byte]) → Either[SchemaError, A]
|
|
76
|
+
↓
|
|
77
|
+
6. YamlOptions controls output formatting
|
|
78
|
+
- Pretty-printing with document markers
|
|
79
|
+
- Compact output without markers
|
|
80
|
+
- Custom indentation and style
|
|
81
|
+
↓
|
|
82
|
+
7. Yaml AST provides structured representation
|
|
83
|
+
- Mapping (key-value pairs)
|
|
84
|
+
- Sequence (ordered lists)
|
|
85
|
+
- Scalar (string values with optional tags)
|
|
86
|
+
- NullValue (YAML null)
|
|
87
|
+
↓
|
|
88
|
+
8. Errors include location traces
|
|
89
|
+
Shows path (.field[index].nested) to error location
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Typical workflow:**
|
|
93
|
+
|
|
94
|
+
A user type flows through the derivation and encoding pipeline as follows:
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
User type (e.g., case class Config)
|
|
98
|
+
↓
|
|
99
|
+
Schema.derived (automatic via macro)
|
|
100
|
+
↓
|
|
101
|
+
Schema[Config].derive(YamlFormat) → YamlCodec[Config]
|
|
102
|
+
↓
|
|
103
|
+
Use codec.encodeToString(config) to serialize → String
|
|
104
|
+
Use codec.decode(yamlString) to deserialize → Either[SchemaError, Config]
|
|
105
|
+
↓
|
|
106
|
+
Handle SchemaError with location trace on failure
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Type Relationships
|
|
110
|
+
|
|
111
|
+
- **`Yaml`** — Sealed trait AST representing YAML data structures
|
|
112
|
+
- **`YamlCodec[A]`** — Main public API; contains encoder and decoder for bidirectional serialization
|
|
113
|
+
- **`YamlCodecDeriver`** — Configuration and derivation system; generates codecs from Schema
|
|
114
|
+
- **`YamlOptions`** — Configuration for output formatting (pretty, compact, indentation)
|
|
115
|
+
- **`YamlReader`, `YamlWriter`** — Low-level YAML parsing and serialization
|
|
116
|
+
|
|
117
|
+
## Common Patterns
|
|
118
|
+
|
|
119
|
+
This section shows practical patterns for working with YAML codecs in real-world scenarios.
|
|
120
|
+
|
|
121
|
+
### Pattern 1: Derive and Encode a Configuration Record
|
|
122
|
+
|
|
123
|
+
To derive and use a YAML codec for a record type:
|
|
124
|
+
|
|
125
|
+
```scala
|
|
126
|
+
import zio.blocks.schema._
|
|
127
|
+
import zio.blocks.schema.yaml._
|
|
128
|
+
|
|
129
|
+
case class AppConfig(name: String, port: Int, debug: Boolean)
|
|
130
|
+
|
|
131
|
+
object AppConfig {
|
|
132
|
+
implicit val schema: Schema[AppConfig] = Schema.derived[AppConfig]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
val codec = AppConfig.schema.derive(YamlFormat)
|
|
136
|
+
val config = AppConfig("MyApp", 8080, true)
|
|
137
|
+
val yamlString = codec.encodeToString(config)
|
|
138
|
+
println(yamlString)
|
|
139
|
+
// name: MyApp
|
|
140
|
+
// port: 8080
|
|
141
|
+
// debug: true
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Pattern 2: Decode YAML with Error Handling
|
|
145
|
+
|
|
146
|
+
When decoding YAML data, errors include location traces showing where the problem occurred.
|
|
147
|
+
|
|
148
|
+
To decode YAML and handle errors with location information:
|
|
149
|
+
|
|
150
|
+
```scala
|
|
151
|
+
import zio.blocks.schema._
|
|
152
|
+
import zio.blocks.schema.yaml._
|
|
153
|
+
|
|
154
|
+
case class DatabaseConfig(host: String, port: Int, username: String)
|
|
155
|
+
|
|
156
|
+
object DatabaseConfig {
|
|
157
|
+
implicit val schema: Schema[DatabaseConfig] = Schema.derived
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
val codec = DatabaseConfig.schema.derive(YamlFormat)
|
|
161
|
+
val yaml = """
|
|
162
|
+
host: localhost
|
|
163
|
+
port: invalid
|
|
164
|
+
username: admin
|
|
165
|
+
"""
|
|
166
|
+
|
|
167
|
+
val result = codec.decode(yaml)
|
|
168
|
+
|
|
169
|
+
result match {
|
|
170
|
+
case Right(config) => println(s"Loaded: $config")
|
|
171
|
+
case Left(error) =>
|
|
172
|
+
println(s"Error: ${error.getMessage}")
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Pattern 3: Pretty-Print with Configuration
|
|
177
|
+
|
|
178
|
+
Use `YamlOptions` to control output formatting with indentation and document markers.
|
|
179
|
+
|
|
180
|
+
To encode with pretty-printing:
|
|
181
|
+
|
|
182
|
+
```scala
|
|
183
|
+
import zio.blocks.schema._
|
|
184
|
+
import zio.blocks.schema.yaml._
|
|
185
|
+
|
|
186
|
+
case class Server(name: String, endpoints: List[String], timeout: Int)
|
|
187
|
+
|
|
188
|
+
object Server {
|
|
189
|
+
implicit val schema: Schema[Server] = Schema.derived
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
val codec = Server.schema.derive(YamlFormat)
|
|
193
|
+
val server = Server("api-server", List("GET /health", "POST /data"), 30)
|
|
194
|
+
|
|
195
|
+
val prettyYaml = codec.encodeToString(server)
|
|
196
|
+
// ---
|
|
197
|
+
// name: api-server
|
|
198
|
+
// endpoints:
|
|
199
|
+
// - GET /health
|
|
200
|
+
// - POST /data
|
|
201
|
+
// timeout: 30
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Pattern 4: Handle Recursive Types
|
|
205
|
+
|
|
206
|
+
Recursive types (types that reference themselves) are fully supported with automatic cycle detection.
|
|
207
|
+
|
|
208
|
+
To define and encode a recursive data structure:
|
|
209
|
+
|
|
210
|
+
```scala
|
|
211
|
+
import zio.blocks.schema._
|
|
212
|
+
import zio.blocks.schema.yaml._
|
|
213
|
+
|
|
214
|
+
sealed trait TreeNode
|
|
215
|
+
case class Leaf(value: String) extends TreeNode
|
|
216
|
+
case class Branch(label: String, children: List[TreeNode]) extends TreeNode
|
|
217
|
+
|
|
218
|
+
object TreeNode {
|
|
219
|
+
implicit val schema: Schema[TreeNode] = Schema.derived
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
val codec = TreeNode.schema.derive(YamlFormat)
|
|
223
|
+
val tree: TreeNode = Branch("root", List(Leaf("a"), Branch("b", List(Leaf("c")))))
|
|
224
|
+
val yaml = codec.encodeToString(tree)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Pattern 5: YAML-JSON Interoperability
|
|
228
|
+
|
|
229
|
+
Convert between YAML and JSON representations seamlessly using YamlJsonInterop.
|
|
230
|
+
|
|
231
|
+
To convert Yaml to Json:
|
|
232
|
+
|
|
233
|
+
```scala
|
|
234
|
+
import zio.blocks.schema.yaml._
|
|
235
|
+
import zio.blocks.schema.json._
|
|
236
|
+
|
|
237
|
+
val yamlString = """
|
|
238
|
+
name: Alice
|
|
239
|
+
age: 30
|
|
240
|
+
"""
|
|
241
|
+
|
|
242
|
+
val yaml = YamlReader.read(yamlString)
|
|
243
|
+
val json = yaml.toJson
|
|
244
|
+
// json represents the same data as JSON
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## Yaml
|
|
250
|
+
|
|
251
|
+
Sealed trait representing a YAML node. Provides a complete AST for YAML data with four possible cases: `Mapping`, `Sequence`, `Scalar`, and `NullValue`.
|
|
252
|
+
|
|
253
|
+
### Overview
|
|
254
|
+
|
|
255
|
+
`Yaml` is a sealed trait that represents any valid YAML value. It can be constructed directly or derived from codecs.
|
|
256
|
+
|
|
257
|
+
### YAML AST Structure
|
|
258
|
+
|
|
259
|
+
To work with the YAML AST directly:
|
|
260
|
+
|
|
261
|
+
```scala
|
|
262
|
+
import zio.blocks.schema.yaml._
|
|
263
|
+
|
|
264
|
+
// Create a mapping (key-value pairs)
|
|
265
|
+
val mapping = Yaml.Mapping.fromStringKeys(
|
|
266
|
+
"name" -> Yaml.Scalar("Alice"),
|
|
267
|
+
"age" -> Yaml.Scalar("30")
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
// Create a sequence (ordered list)
|
|
271
|
+
val sequence = Yaml.Sequence(
|
|
272
|
+
Yaml.Scalar("item1"),
|
|
273
|
+
Yaml.Scalar("item2")
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
// Create a scalar (string value)
|
|
277
|
+
val scalar = Yaml.Scalar("hello")
|
|
278
|
+
|
|
279
|
+
// The null value
|
|
280
|
+
val nullValue = Yaml.NullValue
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Printing YAML
|
|
284
|
+
|
|
285
|
+
Format YAML nodes using compact or pretty-printed output:
|
|
286
|
+
|
|
287
|
+
```scala
|
|
288
|
+
import zio.blocks.schema.yaml._
|
|
289
|
+
|
|
290
|
+
val yaml = Yaml.Mapping.fromStringKeys(
|
|
291
|
+
"name" -> Yaml.Scalar("Bob"),
|
|
292
|
+
"active" -> Yaml.Scalar("true")
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
val compact = yaml.print
|
|
296
|
+
// name: Bob
|
|
297
|
+
// active: true
|
|
298
|
+
|
|
299
|
+
val pretty = yaml.printPretty
|
|
300
|
+
// ---
|
|
301
|
+
// name: Bob
|
|
302
|
+
// active: true
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Converting to JSON
|
|
306
|
+
|
|
307
|
+
Transform Yaml nodes to JSON for interoperability:
|
|
308
|
+
|
|
309
|
+
```scala
|
|
310
|
+
import zio.blocks.schema.yaml._
|
|
311
|
+
|
|
312
|
+
val yaml = Yaml.Scalar("42")
|
|
313
|
+
val json = yaml.toJson
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## YamlCodec[A]
|
|
319
|
+
|
|
320
|
+
Main codec type for encoding and decoding values to and from YAML. Contains encoder and decoder for bidirectional serialization.
|
|
321
|
+
|
|
322
|
+
### Overview
|
|
323
|
+
|
|
324
|
+
`YamlCodec[A]` holds both an encoder and decoder, providing a complete solution for serializing and deserializing values in YAML format. The codec is derived automatically from a `Schema[A]`.
|
|
325
|
+
|
|
326
|
+
### Encoding Values to String
|
|
327
|
+
|
|
328
|
+
Use the codec to convert values to YAML strings:
|
|
329
|
+
|
|
330
|
+
```scala
|
|
331
|
+
import zio.blocks.schema._
|
|
332
|
+
import zio.blocks.schema.yaml._
|
|
333
|
+
|
|
334
|
+
case class Person(name: String, email: String)
|
|
335
|
+
|
|
336
|
+
object Person {
|
|
337
|
+
implicit val schema: Schema[Person] = Schema.derived
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
val codec = Person.schema.derive(YamlFormat)
|
|
341
|
+
val person = Person("Alice", "alice@example.com")
|
|
342
|
+
val yaml = codec.encodeToString(person)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Encoding Values to Byte Array
|
|
346
|
+
|
|
347
|
+
Convert values to YAML bytes:
|
|
348
|
+
|
|
349
|
+
```scala
|
|
350
|
+
import zio.blocks.schema._
|
|
351
|
+
import zio.blocks.schema.yaml._
|
|
352
|
+
|
|
353
|
+
case class Data(timestamp: Long, value: String)
|
|
354
|
+
|
|
355
|
+
object Data {
|
|
356
|
+
implicit val schema: Schema[Data] = Schema.derived
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
val codec = Data.schema.derive(YamlFormat)
|
|
360
|
+
val data = Data(System.currentTimeMillis(), "sample")
|
|
361
|
+
val bytes = codec.encode(data)
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Decoding Values from String
|
|
365
|
+
|
|
366
|
+
Use the codec to convert YAML strings back to values:
|
|
367
|
+
|
|
368
|
+
```scala
|
|
369
|
+
import zio.blocks.schema._
|
|
370
|
+
import zio.blocks.schema.yaml._
|
|
371
|
+
|
|
372
|
+
case class Config(host: String, port: Int)
|
|
373
|
+
|
|
374
|
+
object Config {
|
|
375
|
+
implicit val schema: Schema[Config] = Schema.derived
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
val codec = Config.schema.derive(YamlFormat)
|
|
379
|
+
val yaml = """
|
|
380
|
+
host: localhost
|
|
381
|
+
port: 8080
|
|
382
|
+
"""
|
|
383
|
+
|
|
384
|
+
val result: Either[zio.blocks.schema.SchemaError, Config] = codec.decode(yaml)
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Decoding Values from Byte Array
|
|
388
|
+
|
|
389
|
+
Read and decode values from YAML bytes:
|
|
390
|
+
|
|
391
|
+
```scala
|
|
392
|
+
import zio.blocks.schema._
|
|
393
|
+
import zio.blocks.schema.yaml._
|
|
394
|
+
|
|
395
|
+
case class Settings(debug: Boolean, timeout: Int)
|
|
396
|
+
|
|
397
|
+
object Settings {
|
|
398
|
+
implicit val schema: Schema[Settings] = Schema.derived
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
val codec = Settings.schema.derive(YamlFormat)
|
|
402
|
+
// Use encoded bytes from a previous encoding
|
|
403
|
+
val settings = Settings(debug = true, timeout = 30)
|
|
404
|
+
val bytes = codec.encodeToString(settings).getBytes("UTF-8")
|
|
405
|
+
|
|
406
|
+
val result = codec.decode(bytes)
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## YamlCodecDeriver
|
|
412
|
+
|
|
413
|
+
Configuration and derivation system for creating `YamlCodec[A]` instances from `Schema[A]`.
|
|
414
|
+
|
|
415
|
+
### Overview
|
|
416
|
+
|
|
417
|
+
`YamlCodecDeriver` implements the schema-driven derivation of YAML codecs. It automatically handles 27 primitive types and complex types (records, variants, sequences, maps), generating appropriate YAML encoders and decoders.
|
|
418
|
+
|
|
419
|
+
### How Derivation Works
|
|
420
|
+
|
|
421
|
+
To create a codec from a schema:
|
|
422
|
+
|
|
423
|
+
```scala
|
|
424
|
+
import zio.blocks.schema._
|
|
425
|
+
import zio.blocks.schema.yaml._
|
|
426
|
+
|
|
427
|
+
case class User(id: Int, name: String, active: Boolean)
|
|
428
|
+
|
|
429
|
+
object User {
|
|
430
|
+
implicit val schema: Schema[User] = Schema.derived
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
val codec = User.schema.derive(YamlFormat)
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Primitive Type Support
|
|
437
|
+
|
|
438
|
+
All 27 ZIO Schema primitives are supported:
|
|
439
|
+
- Numeric: `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `BigInt`, `BigDecimal`
|
|
440
|
+
- Logical: `Boolean`, `Char`, `String`
|
|
441
|
+
- Temporal: `Instant`, `LocalDate`, `LocalDateTime`, `LocalTime`, `Duration`, `Period`, `Year`, `YearMonth`, `MonthDay`, `Month`, `DayOfWeek`, `ZonedDateTime`, `OffsetDateTime`, `OffsetTime`, `ZoneId`, `ZoneOffset`
|
|
442
|
+
- Special: `UUID`, `Currency`, `Unit`
|
|
443
|
+
|
|
444
|
+
### Record Type Support
|
|
445
|
+
|
|
446
|
+
Case classes (records) are fully supported. Each field becomes a named key in the YAML mapping:
|
|
447
|
+
|
|
448
|
+
```scala
|
|
449
|
+
import zio.blocks.schema._
|
|
450
|
+
import zio.blocks.schema.yaml._
|
|
451
|
+
|
|
452
|
+
case class Address(street: String, city: String, zipCode: String)
|
|
453
|
+
|
|
454
|
+
object Address {
|
|
455
|
+
implicit val schema: Schema[Address] = Schema.derived
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
val codec = Address.schema.derive(YamlFormat)
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Variant Type Support
|
|
462
|
+
|
|
463
|
+
Sealed traits and sum types are encoded as YAML mappings with discriminator information:
|
|
464
|
+
|
|
465
|
+
```scala
|
|
466
|
+
import zio.blocks.schema._
|
|
467
|
+
import zio.blocks.schema.yaml._
|
|
468
|
+
|
|
469
|
+
sealed trait Status
|
|
470
|
+
case class Running(pid: Int) extends Status
|
|
471
|
+
case class Stopped(exitCode: Int) extends Status
|
|
472
|
+
|
|
473
|
+
object Status {
|
|
474
|
+
implicit val schema: Schema[Status] = Schema.derived
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
val codec = Status.schema.derive(YamlFormat)
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
## YamlOptions
|
|
483
|
+
|
|
484
|
+
Configuration for YAML output formatting. Controls indentation, document markers, and presentation style.
|
|
485
|
+
|
|
486
|
+
### Overview
|
|
487
|
+
|
|
488
|
+
`YamlOptions` provides predefined configurations and factory methods for customizing YAML serialization output.
|
|
489
|
+
|
|
490
|
+
### Pretty-Printing Configuration
|
|
491
|
+
|
|
492
|
+
Enable pretty-printed output with document markers:
|
|
493
|
+
|
|
494
|
+
```scala
|
|
495
|
+
import zio.blocks.schema.yaml._
|
|
496
|
+
|
|
497
|
+
val prettyOptions = YamlOptions.pretty
|
|
498
|
+
// Enables:
|
|
499
|
+
// - Document markers (---)
|
|
500
|
+
// - Indentation (default 2 spaces)
|
|
501
|
+
// - Readable formatting
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### Compact Output
|
|
505
|
+
|
|
506
|
+
Use compact formatting without document markers:
|
|
507
|
+
|
|
508
|
+
```scala
|
|
509
|
+
import zio.blocks.schema.yaml._
|
|
510
|
+
|
|
511
|
+
val compactOptions = YamlOptions.default
|
|
512
|
+
// Disables document markers for inline or file formats
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
---
|
|
516
|
+
|
|
517
|
+
## Error Handling
|
|
518
|
+
|
|
519
|
+
YAML decoding errors include location traces showing the path through nested structures where the error occurred.
|
|
520
|
+
|
|
521
|
+
### Understanding Error Traces
|
|
522
|
+
|
|
523
|
+
Errors render as paths like `.field[0].nested.value` showing exactly where decoding failed:
|
|
524
|
+
|
|
525
|
+
```scala
|
|
526
|
+
import zio.blocks.schema._
|
|
527
|
+
import zio.blocks.schema.yaml._
|
|
528
|
+
|
|
529
|
+
case class Team(name: String, members: List[String])
|
|
530
|
+
|
|
531
|
+
object Team {
|
|
532
|
+
implicit val schema: Schema[Team] = Schema.derived
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
val codec = Team.schema.derive(YamlFormat)
|
|
536
|
+
val invalidYaml = """
|
|
537
|
+
name: Engineering
|
|
538
|
+
members: invalid
|
|
539
|
+
"""
|
|
540
|
+
|
|
541
|
+
val result = codec.decode(invalidYaml)
|
|
542
|
+
|
|
543
|
+
result match {
|
|
544
|
+
case Right(team) => println(s"Loaded: $team")
|
|
545
|
+
case Left(error) =>
|
|
546
|
+
println(s"Error: ${error.getMessage}")
|
|
547
|
+
}
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### Zero-Overhead Error Handling
|
|
551
|
+
|
|
552
|
+
Errors use zero-overhead exceptions (no stack traces) for efficient error reporting in scenarios where errors are expected and handled inline.
|
|
@@ -48,26 +48,26 @@ val result: Either[SchemaError, Person] = Person.codec.decode(bytes)
|
|
|
48
48
|
To include the base schema module with JSON support, add the following dependency to your `build.sbt`:
|
|
49
49
|
|
|
50
50
|
```scala
|
|
51
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema" % "0.0.
|
|
51
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema" % "0.0.51"
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Additional format modules are separate artifacts:
|
|
55
55
|
|
|
56
56
|
```scala
|
|
57
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "0.0.
|
|
58
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "0.0.
|
|
59
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-csv" % "0.0.
|
|
60
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "0.0.
|
|
61
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "0.0.
|
|
62
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "0.0.
|
|
63
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-xml" % "0.0.
|
|
64
|
-
libraryDependencies += "dev.zio" %% "zio-blocks-schema-yaml" % "0.0.
|
|
57
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "0.0.51"
|
|
58
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "0.0.51"
|
|
59
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-csv" % "0.0.51"
|
|
60
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "0.0.51"
|
|
61
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "0.0.51"
|
|
62
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "0.0.51"
|
|
63
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-xml" % "0.0.51"
|
|
64
|
+
libraryDependencies += "dev.zio" %% "zio-blocks-schema-yaml" % "0.0.51"
|
|
65
65
|
```
|
|
66
66
|
|
|
67
67
|
For cross-platform projects (Scala.js):
|
|
68
68
|
|
|
69
69
|
```scala
|
|
70
|
-
libraryDependencies += "dev.zio" %%% "zio-blocks-schema" % "0.0.
|
|
70
|
+
libraryDependencies += "dev.zio" %%% "zio-blocks-schema" % "0.0.51"
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
Supported Scala versions: 2.13.x and 3.x.
|