@zio.dev/zio-blocks 0.0.32 → 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.
Files changed (152) hide show
  1. package/guides/compile-time-resource-safety-with-scope.md +16 -17
  2. package/guides/getting-started-with-mux.md +1507 -0
  3. package/guides/query-dsl-extending.md +161 -102
  4. package/guides/query-dsl-fluent-builder.md +217 -157
  5. package/guides/query-dsl-reified-optics.md +12 -10
  6. package/guides/query-dsl-sql.md +246 -165
  7. package/guides/telemetry-guide.md +1069 -0
  8. package/guides/zio-schema-migration.md +29 -22
  9. package/index.md +293 -51
  10. package/package.json +1 -1
  11. package/plans/config-follow-up-prs.md +188 -0
  12. package/plans/config-pr-assessment-roadmap.md +310 -0
  13. package/reference/MuxDataFlow.jsx +250 -0
  14. package/reference/async.md +651 -0
  15. package/reference/chunk.md +3533 -308
  16. package/reference/codegen/case-class.md +436 -0
  17. package/reference/codegen/emitter-config.md +383 -0
  18. package/reference/codegen/examples.md +664 -0
  19. package/reference/codegen/field.md +316 -0
  20. package/reference/codegen/index.md +317 -0
  21. package/reference/codegen/scala-emitter.md +392 -0
  22. package/reference/codegen/scala-file.md +276 -0
  23. package/reference/codegen/sealed-trait.md +408 -0
  24. package/reference/codegen/type-definition.md +340 -0
  25. package/reference/codegen/type-ref.md +201 -0
  26. package/reference/combinators.md +347 -117
  27. package/reference/config.md +158 -0
  28. package/reference/context.md +4 -4
  29. package/reference/datastar.md +346 -0
  30. package/reference/docs.md +1461 -345
  31. package/reference/endpoint/auth-type.md +146 -0
  32. package/reference/endpoint/endpoint.md +297 -0
  33. package/reference/endpoint/http-codec.md +249 -0
  34. package/reference/endpoint/index.md +825 -0
  35. package/reference/endpoint/path-codec.md +237 -0
  36. package/reference/endpoint/route-pattern.md +196 -0
  37. package/reference/endpoint/route-tree.md +111 -0
  38. package/reference/endpoint/segment-codec.md +212 -0
  39. package/reference/html.md +1120 -0
  40. package/reference/htmx/attribute-values.md +359 -0
  41. package/reference/htmx/hx-encoding.md +111 -0
  42. package/reference/htmx/hx-params.md +204 -0
  43. package/reference/htmx/hx-swap.md +276 -0
  44. package/reference/htmx/hx-sync.md +251 -0
  45. package/reference/htmx/hx-target.md +314 -0
  46. package/reference/htmx/hx-trigger.md +457 -0
  47. package/reference/htmx/hx-url-update.md +239 -0
  48. package/reference/htmx/index.md +855 -0
  49. package/reference/http-model/index.md +47 -0
  50. package/reference/http-model/model.md +1481 -0
  51. package/reference/http-model/schema.md +747 -0
  52. package/reference/maybe.md +826 -0
  53. package/reference/media-type.md +2 -2
  54. package/reference/mux.mdx +823 -0
  55. package/reference/openapi.md +1351 -0
  56. package/reference/resource-management/defer-handle.md +1 -1
  57. package/reference/resource-management/resource.md +31 -2
  58. package/reference/resource-management/scope.md +28 -12
  59. package/reference/resource-management/wire.md +3 -7
  60. package/reference/ringbuffer/MpmcDiagram.jsx +717 -0
  61. package/reference/ringbuffer/MpscDiagram.jsx +618 -0
  62. package/reference/ringbuffer/SpmcDiagram.jsx +680 -0
  63. package/reference/ringbuffer/SpscDiagram.jsx +677 -0
  64. package/reference/ringbuffer/advanced.mdx +109 -0
  65. package/reference/ringbuffer/index.mdx +145 -0
  66. package/reference/ringbuffer/mpmc.mdx +151 -0
  67. package/reference/ringbuffer/mpsc.mdx +132 -0
  68. package/reference/ringbuffer/spmc.mdx +108 -0
  69. package/reference/ringbuffer/spsc.mdx +344 -0
  70. package/reference/{allows.md → schema/allows.md} +4 -4
  71. package/reference/{binding-resolver.md → schema/binding-resolver.md} +1 -1
  72. package/reference/{binding.md → schema/binding.md} +2 -3
  73. package/reference/schema/built-in-codecs/avro.md +451 -0
  74. package/reference/schema/built-in-codecs/bson.md +480 -0
  75. package/reference/schema/built-in-codecs/csv.md +564 -0
  76. package/reference/schema/built-in-codecs/index.md +77 -0
  77. package/reference/schema/built-in-codecs/json/index.md +295 -0
  78. package/reference/schema/built-in-codecs/json/json-config.md +217 -0
  79. package/reference/{json-patch.md → schema/built-in-codecs/json/json-patch.md} +3 -3
  80. package/reference/{json-schema.md → schema/built-in-codecs/json/json-schema.md} +14 -47
  81. package/reference/schema/built-in-codecs/json/json-selection.md +322 -0
  82. package/reference/{json.md → schema/built-in-codecs/json/json.md} +32 -64
  83. package/reference/schema/built-in-codecs/messagepack.md +508 -0
  84. package/reference/schema/built-in-codecs/thrift.md +433 -0
  85. package/reference/schema/built-in-codecs/toon.md +1078 -0
  86. package/reference/{xml.md → schema/built-in-codecs/xml.md} +34 -192
  87. package/reference/schema/built-in-codecs/yaml.md +552 -0
  88. package/reference/{codec.md → schema/codec.md} +10 -10
  89. package/reference/{dynamic-optic.md → schema/dynamic-optic.md} +151 -5
  90. package/reference/{dynamic-schema.md → schema/dynamic-schema.md} +8 -8
  91. package/reference/schema/format.md +92 -0
  92. package/reference/schema/index.md +50 -0
  93. package/reference/schema/migration.md +297 -0
  94. package/reference/{modifier.md → schema/modifier.md} +58 -7
  95. package/reference/{optics.md → schema/optics.md} +2 -2
  96. package/reference/{patch.md → schema/patch.md} +1 -1
  97. package/{path-interpolator.md → reference/schema/path-interpolator.md} +165 -72
  98. package/reference/{schema-evolution → schema/schema-evolution}/as.md +5 -5
  99. package/reference/{schema-evolution → schema/schema-evolution}/index.md +2 -2
  100. package/reference/{schema-evolution → schema/schema-evolution}/into.md +3 -3
  101. package/reference/{schema-expr.md → schema/schema-expr.md} +110 -175
  102. package/reference/{schema.md → schema/schema.md} +13 -1
  103. package/reference/{structural-types.md → schema/structural-types.md} +1 -1
  104. package/reference/{type-class-derivation.md → schema/type-class-derivation.md} +63 -1
  105. package/reference/smithy.md +533 -0
  106. package/reference/sql/db-codec-deriver.md +71 -0
  107. package/reference/sql/db-codec.md +687 -0
  108. package/reference/sql/db-con.md +271 -0
  109. package/reference/sql/db-connection.md +153 -0
  110. package/reference/sql/db-param-writer.md +77 -0
  111. package/reference/sql/db-param.md +66 -0
  112. package/reference/sql/db-result-reader.md +146 -0
  113. package/reference/sql/db-tx.md +82 -0
  114. package/reference/sql/db-value.md +41 -0
  115. package/reference/sql/ddl.md +85 -0
  116. package/reference/sql/frag.md +254 -0
  117. package/reference/sql/index.md +341 -0
  118. package/reference/sql/repo.md +600 -0
  119. package/reference/sql/sql-dialect.md +73 -0
  120. package/reference/sql/sql-logger.md +62 -0
  121. package/reference/sql/sql-name-mapper.md +70 -0
  122. package/reference/sql/table-metadata.md +134 -0
  123. package/reference/sql/table.md +448 -0
  124. package/reference/sql/transactor-zio.md +399 -0
  125. package/reference/sql/transactor.md +353 -0
  126. package/reference/sql-zio.md +112 -0
  127. package/reference/streams/concurrent-operators.md +106 -0
  128. package/reference/streams/index.md +653 -0
  129. package/reference/streams/pipeline.md +718 -0
  130. package/reference/streams/reader.md +1284 -0
  131. package/reference/streams/scala-2-compatibility.md +55 -0
  132. package/reference/streams/sink.md +1426 -0
  133. package/reference/streams/stream.md +2526 -0
  134. package/reference/streams/writer.md +1045 -0
  135. package/reference/streams/zero-boxing.md +275 -0
  136. package/reference/telemetry.md +693 -0
  137. package/reference/typeid.md +2922 -583
  138. package/sidebars.js +238 -43
  139. package/superpowers/plans/2026-03-19-docs-critique-subagent.md +407 -0
  140. package/superpowers/specs/2026-03-19-docs-critique-subagent-design.md +222 -0
  141. package/reference/formats.md +0 -694
  142. package/reference/http-model.md +0 -1716
  143. package/reference/streams.md +0 -989
  144. package/ringbuffer.md +0 -249
  145. /package/reference/{json-differ.md → schema/built-in-codecs/json/json-differ.md} +0 -0
  146. /package/reference/{dynamic-value.md → schema/dynamic-value.md} +0 -0
  147. /package/reference/{lazy.md → schema/lazy.md} +0 -0
  148. /package/reference/{reflect.md → schema/reflect.md} +0 -0
  149. /package/reference/{registers.md → schema/registers.md} +0 -0
  150. /package/reference/{schema-error.md → schema/schema-error.md} +0 -0
  151. /package/reference/{syntax.md → schema/syntax.md} +0 -0
  152. /package/reference/{validation.md → schema/validation.md} +0 -0
@@ -1,694 +0,0 @@
1
- ---
2
- id: formats
3
- title: "Serialization Formats"
4
- sidebar_label: "Formats"
5
- ---
6
-
7
- ZIO Blocks Schema provides automatic codec derivation for multiple serialization formats. Once you have a `Schema[A]` for your data type, you can derive codecs for any supported format using the unified `Schema.derive(Format)` pattern.
8
-
9
- A `Format` is an abstraction that bundles together everything needed to serialize and deserialize data in a specific format (JSON, Avro, Protobuf, etc.).
10
-
11
- ## Overview
12
-
13
- Each format defines the types of input for decoding and output for encoding, as well as the typeclass used as a codec for that format. Each format contains a `Deriver` corresponding to its specific MIME type, which is used to derive codecs from schemas:
14
-
15
- ```scala
16
- trait Format {
17
- type DecodeInput
18
- type EncodeOutput
19
- type TypeClass[A] <: Codec[DecodeInput, EncodeOutput, A]
20
- def mimeType: String
21
- def deriver: Deriver[TypeClass]
22
- }
23
- ```
24
-
25
- It unifies all metadata related to serialization formats, such as MIME type and codec deriver, in a single place. This allows for a consistent API across different formats when deriving codecs from schemas. Having MIME type information helps with runtime content negotiation and format routing, for example in HTTP servers or message queues.
26
-
27
- That is, you can easily call [`Schema[A].derive(format)`](./type-class-derivation.md#using-the-deriver-to-derive-type-class-instances) for any format that implements the `Format` trait, and receive a codec that can encode and decode values of type `A` according to the rules of that format.
28
-
29
- Formats are categorized into `BinaryFormat` and `TextFormat`, which specify the types of input and output for encoding and decoding:
30
-
31
- ```scala
32
- sealed trait Format
33
- abstract class BinaryFormat[...](...) extends Format { ... }
34
- abstract class TextFormat[...](...) extends Format { ... }
35
- ```
36
-
37
- For example, the `JsonFormat` is a `BinaryFormat` that represents a JSON binary format, where the input for decoding is `ByteBuffer` and the output for encoding is also `ByteBuffer`, the MIME type is `application/json`, and the deriver for generating codecs from schemas is `JsonCodecDeriver`:
38
-
39
- ```scala
40
- object JsonFormat extends BinaryFormat("application/json", JsonCodecDeriver)
41
- ```
42
-
43
- ## Built-in Formats
44
-
45
- Here's a summary of the formats currently supported by ZIO Blocks. Each format provides a `BinaryFormat` object that can be passed to `derive`:
46
-
47
- | Format Object | Codec Type | MIME Type | Module |
48
- |---------------------|-----------------------|-----------------------|---------------------------------|
49
- | `JsonFormat` | `JsonCodec[A]` | `application/json` | `zio-blocks-schema` |
50
- | `AvroFormat` | `AvroCodec[A]` | `application/avro` | `zio-blocks-schema-avro` |
51
- | `BsonFormat` | `BsonCodec[A]` | `application/bson` | `zio-blocks-schema-bson` |
52
- | `CsvFormat` | `CsvCodec[A]` | `text/csv` | `zio-blocks-schema-csv` |
53
- | `MessagePackFormat` | `MessagePackCodec[A]` | `application/msgpack` | `zio-blocks-schema-messagepack` |
54
- | `ThriftFormat` | `ThriftCodec[A]` | `application/thrift` | `zio-blocks-schema-thrift` |
55
- | `ToonFormat` | `ToonCodec[A]` | `text/toon` | `zio-blocks-schema-toon` |
56
- | `XmlFormat` | `XmlCodec[A]` | `application/xml` | `zio-blocks-schema-xml` |
57
- | `YamlFormat` | `YamlCodec[A]` | `application/yaml` | `zio-blocks-schema-yaml` |
58
-
59
- ## Defining a Custom Format
60
-
61
- To add a new serialization format, define a `BinaryFormat` (or `TextFormat`) singleton with a custom `Deriver`:
62
-
63
- ```scala
64
- import zio.blocks.schema.codec.{BinaryCodec, BinaryFormat}
65
- import zio.blocks.schema.derive.Deriver
66
-
67
- // 1. Define your codec base class
68
- abstract class MyCodec[A] extends BinaryCodec[A]
69
-
70
- // 2. Implement a Deriver[MyCodec] (see Type-class Derivation docs)
71
- // val myDeriver: Deriver[MyCodec] = ...
72
-
73
- // 3. Create the format singleton
74
- // object MyFormat extends BinaryFormat[MyCodec]("application/x-myformat", myDeriver)
75
- ```
76
-
77
- For details on implementing a `Deriver`, see [Type-class Derivation](./type-class-derivation.md).
78
-
79
- ## Codec Derivation System
80
-
81
- All serialization formats in ZIO Blocks follow the same pattern: given a `Schema[A]`, you derive a codec by calling `derive` with a format object:
82
-
83
- ```scala
84
- import zio.blocks.schema._
85
- import zio.blocks.schema.toon._
86
-
87
- case class Person(name: String, age: Int)
88
-
89
- object Person {
90
- implicit val schema: Schema[Person] = Schema.derived
91
- }
92
-
93
- // Derive codec for any format (using TOON as an example)
94
- val codec = Schema[Person].derive(ToonFormat)
95
-
96
- // Encode to bytes
97
- val bytes: Array[Byte] = codec.encode(Person("Alice", 30))
98
-
99
- // Decode from bytes
100
- val result: Either[SchemaError, Person] = codec.decode(bytes)
101
- ```
102
-
103
- ## JSON Format
104
-
105
- JSON format is the most commonly used text-based serialization format. See the dedicated [JSON documentation](json.md) for comprehensive coverage of the `Json` ADT, navigation, and transformation features.
106
-
107
- ### Installation
108
-
109
- JSON support is included in the core schema module:
110
-
111
- ```scala
112
- libraryDependencies += "dev.zio" %% "zio-blocks-schema" % "<version>"
113
- ```
114
-
115
- ### Basic Usage
116
-
117
- ```scala
118
- import zio.blocks.schema._
119
- import zio.blocks.schema.json._
120
-
121
- case class Person(name: String, age: Int)
122
-
123
- object Person {
124
- implicit val schema: Schema[Person] = Schema.derived
125
- }
126
-
127
- val person = Person("Alice", 30)
128
- val bytes: Array[Byte] = person.toJsonBytes
129
- val decoded: Either[SchemaError, Person] = bytes.fromJson[Person]
130
- ```
131
-
132
- ## Avro Format
133
-
134
- Apache Avro is a compact binary format with schema evolution support, commonly used in big data systems like Kafka and Spark.
135
-
136
- ### Installation
137
-
138
- ```scala
139
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "<version>"
140
- ```
141
-
142
- Requires the Apache Avro library (1.12.x).
143
-
144
- ### Basic Usage
145
-
146
- ```scala
147
- import zio.blocks.schema._
148
- import zio.blocks.schema.avro._
149
-
150
- case class Person(name: String, age: Int)
151
-
152
- object Person {
153
- implicit val schema: Schema[Person] = Schema.derived
154
- }
155
-
156
- // Derive Avro codec
157
- val codec = Schema[Person].derive(AvroFormat)
158
-
159
- // Encode to Avro binary format
160
- val person = Person("Alice", 30)
161
- val bytes: Array[Byte] = codec.encode(person)
162
-
163
- // Decode from Avro binary format
164
- val decoded: Either[SchemaError, Person] = codec.decode(bytes)
165
- ```
166
-
167
- ### Avro Schema Generation
168
-
169
- Each `AvroCodec` exposes an `avroSchema` property containing the Apache Avro schema:
170
-
171
- ```scala
172
- import zio.blocks.schema._
173
- import zio.blocks.schema.avro._
174
- import org.apache.avro.{Schema => AvroSchema}
175
-
176
- case class Person(name: String, age: Int)
177
-
178
- object Person {
179
- implicit val schema: Schema[Person] = Schema.derived
180
- }
181
-
182
- val codec = Schema[Person].derive(AvroFormat)
183
- val avroSchema: AvroSchema = codec.avroSchema
184
- println(avroSchema.toString(true))
185
- // {
186
- // "type": "record",
187
- // "name": "Person",
188
- // "fields": [
189
- // {"name": "name", "type": "string"},
190
- // {"name": "age", "type": "int"}
191
- // ]
192
- // }
193
- ```
194
-
195
- ### Avro Type Mappings
196
-
197
- | Scala Type | Avro Type |
198
- |------------|-----------|
199
- | `Boolean` | `boolean` |
200
- | `Byte`, `Short`, `Int` | `int` |
201
- | `Long` | `long` |
202
- | `Float` | `float` |
203
- | `Double` | `double` |
204
- | `String`, `Char` | `string` |
205
- | `BigInt` | `bytes` |
206
- | `BigDecimal` | Record (mantissa, scale, precision, roundingMode) |
207
- | `UUID` | 16-byte fixed |
208
- | `Currency` | 3-byte fixed |
209
- | `java.time.*` | Records or primitives |
210
- | Case classes | `record` |
211
- | Sealed traits | `union` |
212
- | `List[A]`, `Set[A]` | `array` |
213
- | `Map[String, V]` | `map` |
214
-
215
- ### ADT Encoding
216
-
217
- Sealed traits are encoded as Avro unions with an integer index prefix:
218
-
219
- ```scala
220
- import zio.blocks.schema._
221
- import zio.blocks.schema.avro._
222
-
223
- sealed trait Shape
224
- case class Circle(radius: Double) extends Shape
225
- case class Rectangle(width: Double, height: Double) extends Shape
226
-
227
- object Shape {
228
- implicit val schema: Schema[Shape] = Schema.derived
229
- }
230
-
231
- val codec = Schema[Shape].derive(AvroFormat)
232
-
233
- // The variant index (0 for Circle, 1 for Rectangle) is written first,
234
- // followed by the record data
235
- val circle: Shape = Circle(5.0)
236
- val bytes = codec.encode(circle)
237
- ```
238
-
239
- ## TOON Format (LLM-Optimized)
240
-
241
- TOON (Token-Oriented Object Notation) is a line-oriented, indentation-based text format that encodes the JSON data model with explicit structure and minimal quoting. It is 30-60% more compact than JSON, making it particularly efficient for LLM prompts and responses.
242
-
243
- ### Why TOON?
244
-
245
- - **Token efficient**: 30-60% fewer tokens than equivalent JSON
246
- - **Human readable**: Clean, YAML-like syntax without YAML's complexity
247
- - **LLM optimized**: Designed for AI/ML use cases where token count matters
248
- - **Explicit lengths**: Arrays declare their size upfront for reliable parsing
249
- - **Cross-platform**: Works on JVM and Scala.js
250
-
251
- ### Installation
252
-
253
- ```scala
254
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "<version>"
255
- ```
256
-
257
- ### Basic Usage
258
-
259
- ```scala
260
- import zio.blocks.schema._
261
- import zio.blocks.schema.toon._
262
-
263
- case class Person(name: String, age: Int)
264
-
265
- object Person {
266
- implicit val schema: Schema[Person] = Schema.derived
267
- }
268
-
269
- // Derive TOON codec
270
- val codec = Schema[Person].derive(ToonFormat)
271
-
272
- // Encode to TOON
273
- val person = Person("Alice", 30)
274
- val bytes: Array[Byte] = codec.encode(person)
275
- // name: Alice
276
- // age: 30
277
-
278
- // Decode from TOON
279
- val decoded: Either[SchemaError, Person] = codec.decode(bytes)
280
- ```
281
-
282
- ### TOON Format Examples
283
-
284
- TOON uses indentation and explicit array lengths:
285
-
286
- ```
287
- # Simple object
288
- name: Alice
289
- age: 30
290
- email: alice@example.com
291
-
292
- # Inline primitive arrays (comma-separated)
293
- tags[3]: scala,zio,functional
294
-
295
- # Nested object
296
- address:
297
- street: 123 Main St
298
- city: Springfield
299
-
300
- # Object arrays use list format
301
- orders[2]:
302
- - id: 1
303
- total: 99.99
304
- - id: 2
305
- total: 149.5
306
-
307
- # Or tabular format (more compact)
308
- orders[2]{id,total}:
309
- 1,99.99
310
- 2,149.5
311
- ```
312
-
313
- ### Configuration Options
314
-
315
- The `ToonCodecDeriver` provides extensive configuration:
316
-
317
- ```scala
318
- import zio.blocks.schema._
319
- import zio.blocks.schema.toon._
320
-
321
- case class Person(firstName: String, lastName: String)
322
- object Person {
323
- implicit val schema: Schema[Person] = Schema.derived
324
- }
325
-
326
- // Custom deriver with snake_case field names
327
- val customDeriver = ToonCodecDeriver
328
- .withFieldNameMapper(NameMapper.SnakeCase)
329
- .withArrayFormat(ArrayFormat.Tabular)
330
- .withDiscriminatorKind(DiscriminatorKind.Field("type"))
331
-
332
- val codec = Schema[Person].derive(customDeriver)
333
- // first_name: Alice
334
- // last_name: Smith
335
- ```
336
-
337
- | Option | Description | Default |
338
- |--------|-------------|---------|
339
- | `withFieldNameMapper` | Transform field names (Identity, SnakeCase, KebabCase) | `Identity` |
340
- | `withCaseNameMapper` | Transform variant/case names | `Identity` |
341
- | `withDiscriminatorKind` | ADT discriminator style (Key, Field, None) | `Key` |
342
- | `withArrayFormat` | Array encoding (Auto, Tabular, Inline, List) | `Auto` |
343
- | `withDelimiter` | Inline array delimiter (Comma, Tab, Pipe) | `Comma` |
344
- | `withRejectExtraFields` | Error on unknown fields during decoding | `false` |
345
- | `withEnumValuesAsStrings` | Encode enum values as strings | `true` |
346
- | `withTransientNone` | Omit None values from output | `true` |
347
- | `withTransientEmptyCollection` | Omit empty collections | `true` |
348
- | `withTransientDefaultValue` | Omit fields with default values | `true` |
349
-
350
- ### ADT Encoding Styles
351
-
352
- ```scala
353
- import zio.blocks.schema._
354
- import zio.blocks.schema.toon._
355
-
356
- sealed trait Shape
357
- case class Circle(radius: Double) extends Shape
358
-
359
- object Shape {
360
- implicit val schema: Schema[Shape] = Schema.derived
361
- }
362
-
363
- // Key discriminator (default)
364
- val keyCodec = Schema[Shape].derive(ToonFormat)
365
- // Circle:
366
- // radius: 5
367
-
368
- // Field discriminator
369
- val fieldDeriver = ToonCodecDeriver
370
- .withDiscriminatorKind(DiscriminatorKind.Field("type"))
371
- val fieldCodec = Schema[Shape].derive(fieldDeriver)
372
- // type: Circle
373
- // radius: 5
374
- ```
375
-
376
- ## MessagePack Format
377
-
378
- MessagePack is an efficient binary serialization format that is more compact than JSON while remaining schema-less and cross-language compatible.
379
-
380
- ### Installation
381
-
382
- ```scala
383
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "<version>"
384
- ```
385
-
386
- ### Basic Usage
387
-
388
- ```scala
389
- import zio.blocks.schema._
390
- import zio.blocks.schema.msgpack._
391
-
392
- case class Person(name: String, age: Int)
393
-
394
- object Person {
395
- implicit val schema: Schema[Person] = Schema.derived
396
- }
397
-
398
- // Derive MessagePack codec
399
- val codec = Schema[Person].derive(MessagePackFormat)
400
-
401
- // Encode to MessagePack
402
- val person = Person("Alice", 30)
403
- val bytes: Array[Byte] = codec.encode(person)
404
-
405
- // Decode from MessagePack
406
- val decoded: Either[SchemaError, Person] = codec.decode(bytes)
407
- ```
408
-
409
- ### Binary Efficiency
410
-
411
- MessagePack provides significant space savings compared to JSON:
412
-
413
- - Typically 50-80% of JSON size
414
- - Uses variable-width integer encoding
415
- - No string escaping overhead
416
- - No key quoting or colons/commas
417
-
418
- ### MessagePack Type Mappings
419
-
420
- | Scala Type | MessagePack Type |
421
- |------------|------------------|
422
- | `Unit` | nil |
423
- | `Boolean` | bool |
424
- | `Byte`, `Short`, `Int`, `Long` | int (variable width) |
425
- | `Float` | float32 |
426
- | `Double` | float64 |
427
- | `String`, `Char` | str |
428
- | `Array[Byte]` | bin |
429
- | `List[A]`, `Vector[A]`, `Set[A]` | array |
430
- | `Map[K, V]` | map |
431
- | `Option[A]` | array (0 or 1 element) |
432
- | `Either[A, B]` | map with "left" or "right" key |
433
- | Case classes | map with field names as keys |
434
- | Sealed traits | int index followed by value |
435
-
436
- ### ADT Encoding
437
-
438
- Sealed traits encode a variant index followed by the case value:
439
-
440
- ```scala
441
- import zio.blocks.schema._
442
- import zio.blocks.schema.msgpack._
443
-
444
- sealed trait Shape
445
- case class Circle(radius: Double) extends Shape
446
- case class Rectangle(width: Double, height: Double) extends Shape
447
-
448
- object Shape {
449
- implicit val schema: Schema[Shape] = Schema.derived
450
- }
451
-
452
- val codec = Schema[Shape].derive(MessagePackFormat)
453
-
454
- // Circle is encoded as: 0 followed by {radius: 5.0}
455
- val circle: Shape = Circle(5.0)
456
- val bytes = codec.encode(circle)
457
- ```
458
-
459
- ## BSON Format
460
-
461
- BSON (Binary JSON) is the binary format used by MongoDB. The ZIO Blocks BSON module provides integration with the MongoDB BSON library.
462
-
463
- ### Installation
464
-
465
- ```scala
466
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "<version>"
467
- ```
468
-
469
- Requires the MongoDB BSON library (5.x).
470
-
471
- ### Basic Usage
472
-
473
- ```scala
474
- import zio.blocks.schema._
475
- import zio.blocks.schema.bson._
476
-
477
- case class Person(name: String, age: Int)
478
-
479
- object Person {
480
- implicit val schema: Schema[Person] = Schema.derived
481
- }
482
-
483
- // Derive BSON encoder/decoder
484
- val encoder: BsonEncoder[Person] = BsonSchemaCodec.bsonEncoder(Schema[Person])
485
- val decoder: BsonDecoder[Person] = BsonSchemaCodec.bsonDecoder(Schema[Person])
486
-
487
- // Or get both as a codec
488
- val codec: BsonCodec[Person] = BsonSchemaCodec.bsonCodec(Schema[Person])
489
- ```
490
-
491
- ### MongoDB ObjectId Support
492
-
493
- BSON provides native support for MongoDB ObjectIds:
494
-
495
- ```scala
496
- import zio.blocks.schema._
497
- import zio.blocks.schema.bson._
498
- import org.bson.types.ObjectId
499
-
500
- // Import ObjectId schema
501
- import ObjectIdSupport.objectIdSchema
502
-
503
- case class Document(_id: ObjectId, title: String)
504
-
505
- object Document {
506
- implicit val schema: Schema[Document] = Schema.derived
507
- }
508
-
509
- // ObjectId is encoded using BSON's native OBJECT_ID type
510
- val codec = BsonSchemaCodec.bsonCodec(Schema[Document])
511
- ```
512
-
513
- ### Configuration Options
514
-
515
- ```scala
516
- import zio.blocks.schema._
517
- import zio.blocks.schema.bson._
518
- import BsonSchemaCodec._
519
-
520
- case class Person(name: String, age: Int)
521
- object Person {
522
- implicit val schema: Schema[Person] = Schema.derived
523
- }
524
-
525
- // Custom configuration
526
- val config = Config
527
- .withSumTypeHandling(SumTypeHandling.DiscriminatorField("_type"))
528
- .withIgnoreExtraFields(true)
529
- .withNativeObjectId(true)
530
-
531
- val codec = BsonSchemaCodec.bsonCodec(Schema[Person], config)
532
- ```
533
-
534
- | Option | Description | Default |
535
- |--------|-------------|---------|
536
- | `withSumTypeHandling` | ADT discrimination strategy | `WrapperWithClassNameField` |
537
- | `withClassNameMapping` | Transform class names | `identity` |
538
- | `withIgnoreExtraFields` | Ignore unknown fields on decode | `true` |
539
- | `withNativeObjectId` | Use native BSON ObjectId type | `false` |
540
-
541
- ### Sum Type Handling
542
-
543
- ```scala
544
- import zio.blocks.schema.bson.BsonSchemaCodec.SumTypeHandling
545
-
546
- // Option 1: Wrapper with class name as field key (default)
547
- SumTypeHandling.WrapperWithClassNameField
548
- // {"Circle": {"radius": 5.0}}
549
-
550
- // Option 2: Discriminator field
551
- SumTypeHandling.DiscriminatorField("_type")
552
- // {"_type": "Circle", "radius": 5.0}
553
-
554
- // Option 3: No discriminator (tries each case)
555
- SumTypeHandling.NoDiscriminator
556
- ```
557
-
558
- ## Thrift Format
559
-
560
- Apache Thrift is a binary protocol format with field ID-based encoding, supporting forward-compatible schema evolution.
561
-
562
- ### Installation
563
-
564
- ```scala
565
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "<version>"
566
- ```
567
-
568
- Requires the Apache Thrift library (0.22.x).
569
-
570
- ### Basic Usage
571
-
572
- ```scala
573
- import zio.blocks.schema._
574
- import zio.blocks.schema.thrift._
575
- import java.nio.ByteBuffer
576
-
577
- case class Person(name: String, age: Int)
578
-
579
- object Person {
580
- implicit val schema: Schema[Person] = Schema.derived
581
- }
582
-
583
- // Derive Thrift codec
584
- val codec = Schema[Person].derive(ThriftFormat)
585
-
586
- // Encode to Thrift binary format
587
- val person = Person("Alice", 30)
588
- val bytes: Array[Byte] = codec.encode(person)
589
-
590
- // Decode from Thrift binary format
591
- val decoded: Either[SchemaError, Person] = codec.decode(bytes)
592
-
593
- // ByteBuffer API
594
- val buffer = ByteBuffer.allocate(1024)
595
- codec.encode(person, buffer)
596
- buffer.flip()
597
- val fromBuffer: Either[SchemaError, Person] = codec.decode(buffer)
598
- ```
599
-
600
- ### Thrift-Specific Features
601
-
602
- - **Field ID-based encoding**: Uses 1-based field IDs corresponding to case class field positions
603
- - **Forward compatibility**: Unknown fields are skipped during decoding
604
- - **Out-of-order decoding**: Fields can arrive in any order on the wire
605
- - **TBinaryProtocol**: Uses the standard Thrift binary protocol
606
-
607
- ### Thrift Type Mappings
608
-
609
- | Scala Type | Thrift Type |
610
- |------------|-------------|
611
- | `Unit` | VOID |
612
- | `Boolean` | BOOL |
613
- | `Byte` | BYTE |
614
- | `Short`, `Char` | I16 |
615
- | `Int` | I32 |
616
- | `Long` | I64 |
617
- | `Float`, `Double` | DOUBLE |
618
- | `String` | STRING |
619
- | `BigInt` | Binary (STRING) |
620
- | `BigDecimal` | STRUCT |
621
- | `java.time.*` | STRING (ISO format) or I32 |
622
- | `List[A]` | LIST |
623
- | `Map[K, V]` | MAP |
624
- | Case classes | STRUCT |
625
- | Sealed traits | Indexed variant |
626
-
627
- ## Supported Types
628
-
629
- All formats support the full set of ZIO Blocks Schema primitive types:
630
-
631
- **Numeric Types**:
632
- - `Boolean`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `Char`
633
- - `BigInt`, `BigDecimal`
634
-
635
- **Text Types**:
636
- - `String`
637
-
638
- **Special Types**:
639
- - `Unit`, `UUID`, `Currency`
640
-
641
- **Java Time Types**:
642
- - `Instant`, `LocalDate`, `LocalTime`, `LocalDateTime`
643
- - `OffsetTime`, `OffsetDateTime`, `ZonedDateTime`
644
- - `Duration`, `Period`
645
- - `Year`, `YearMonth`, `MonthDay`
646
- - `DayOfWeek`, `Month`
647
- - `ZoneId`, `ZoneOffset`
648
-
649
- **Composite Types**:
650
- - Records (case classes)
651
- - Variants (sealed traits)
652
- - Sequences (`List`, `Vector`, `Set`, `Array`, etc.)
653
- - Maps (`Map[K, V]`)
654
- - Options (`Option[A]`)
655
- - Eithers (`Either[A, B]`)
656
- - Wrappers (newtypes)
657
-
658
- ## Cross-Platform Support
659
-
660
- | Format | JVM | Scala.js |
661
- |--------|-----|----------|
662
- | JSON | ✓ | ✓ |
663
- | TOON | ✓ | ✓ |
664
- | MessagePack | ✓ | ✓ |
665
- | Avro | ✓ | ✗ |
666
- | Thrift | ✓ | ✗ |
667
- | BSON | ✓ | ✗ |
668
-
669
- ## Error Handling
670
-
671
- All formats return `Either[SchemaError, A]` for decoding operations. Errors include path information for debugging:
672
-
673
- ```scala
674
- import zio.blocks.schema._
675
- import zio.blocks.schema.toon._
676
-
677
- case class Person(name: String, age: Int)
678
- object Person {
679
- implicit val schema: Schema[Person] = Schema.derived
680
- }
681
-
682
- val codec = Schema[Person].derive(ToonFormat)
683
-
684
- // Example: decoding invalid bytes
685
- val invalidBytes = "invalid: data\nwrong: format".getBytes
686
- val result = codec.decode(invalidBytes)
687
-
688
- result match {
689
- case Right(person) => println(s"Decoded: $person")
690
- case Left(error) =>
691
- // SchemaError includes information about the decode failure
692
- error.errors.foreach(e => println(s"Error: ${e.message}"))
693
- }
694
- ```