@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
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: messagepack
|
|
3
|
+
title: "MessagePack Codec Module"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
`zio-blocks-schema-messagepack` is a **schema-driven MessagePack codec module** for serializing and deserializing Scala types to and from MessagePack binary format. It provides comprehensive encoding and decoding with support for 27 primitive types, records, variants, sequences, maps, and recursive types. Core types: `MessagePackCodec`, `MessagePackCodecDeriver`, `MessagePackFormat`.
|
|
7
|
+
|
|
8
|
+
The module integrates with MessagePack specification to provide compact binary serialization with automatic schema generation and optimized reader/writer pools for high-performance streaming.
|
|
9
|
+
|
|
10
|
+
## Motivation
|
|
11
|
+
|
|
12
|
+
MessagePack is a compact binary serialization format that achieves smaller payload sizes than JSON while maintaining compatibility and flexibility. It appears widely across distributed systems, real-time streaming, and space-constrained environments. Manually writing MessagePack encoders and decoders is error-prone and repetitive, especially for complex types with records, nested structures, and recursive definitions. `zio-blocks-schema-messagepack` 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 MessagePack type support (all fixint, fixarray, fixmap, ext types, strings, numbers)
|
|
14
|
+
- Automatic schema generation from Scala types
|
|
15
|
+
- Highly optimized encoding with minimal overhead
|
|
16
|
+
- Reader/writer pool management for efficient coding
|
|
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 ByteBuffer
|
|
20
|
+
- Multiple decoding paths: byte arrays and ByteBuffer
|
|
21
|
+
- Cross-platform compatibility (JVM and Scala.js)
|
|
22
|
+
|
|
23
|
+
Rather than writing custom encoders or relying on string-based schema configuration, 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-messagepack" % "0.0.51"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For Scala.js, use `%%%` instead of `%%`:
|
|
34
|
+
|
|
35
|
+
```sbt
|
|
36
|
+
libraryDependencies += "dev.zio" %%% "zio-blocks-schema-messagepack" % "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 MessagePack codec derivation and usage:
|
|
44
|
+
|
|
45
|
+
1. **Define your type** — Any Scala type with a `Schema` instance
|
|
46
|
+
2. **Derive a codec** — Use `Schema.derive(MessagePackFormat)` to obtain a `MessagePackCodec[A]`
|
|
47
|
+
3. **Encode or decode** — Call `codec.encode(value)` or `codec.decode(bytes)`
|
|
48
|
+
4. **Handle errors** — Catch `SchemaError` with location traces showing where the error occurred
|
|
49
|
+
|
|
50
|
+
The derivation process is automatic for all supported types (all 27 primitives, records, variants, sequences, maps). The module automatically generates MessagePack-compatible formats and handles encoding/decoding without manual configuration.
|
|
51
|
+
|
|
52
|
+
## How They Work Together
|
|
53
|
+
|
|
54
|
+
The MessagePack codec pipeline flows through these layers:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
1. User defines Schema[A] for their type
|
|
58
|
+
↓
|
|
59
|
+
2. Schema[A].derive(MessagePackFormat) creates MessagePackCodec[A]
|
|
60
|
+
↓
|
|
61
|
+
3. MessagePackCodecDeriver derives Encoder and Decoder implementations
|
|
62
|
+
- For primitives: type-specific MessagePack encoders/decoders
|
|
63
|
+
- For records: field-by-field composition with map encoding
|
|
64
|
+
- For variants: tagged union encoding
|
|
65
|
+
- For sequences: array encoding/decoding
|
|
66
|
+
- For maps: map encoding/decoding
|
|
67
|
+
↓
|
|
68
|
+
4. MessagePackCodec provides multiple encoding paths
|
|
69
|
+
- encode(value) → Array[Byte]
|
|
70
|
+
- encode(value, buffer: ByteBuffer) → Unit
|
|
71
|
+
↓
|
|
72
|
+
5. MessagePackCodec provides multiple decoding paths
|
|
73
|
+
- decode(bytes: Array[Byte]) → Either[SchemaError, A]
|
|
74
|
+
- decode(buffer: ByteBuffer) → Either[SchemaError, A]
|
|
75
|
+
↓
|
|
76
|
+
6. MessagePackReader/Writer manage I/O with pooling
|
|
77
|
+
- Reader pool: reuses instances for streaming decoding
|
|
78
|
+
- Writer pool: reuses instances for streaming encoding
|
|
79
|
+
- Automatic format detection and type-specific optimization
|
|
80
|
+
↓
|
|
81
|
+
7. Errors include location traces
|
|
82
|
+
Shows path (.field[index].nested) to error location
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Typical workflow:**
|
|
86
|
+
|
|
87
|
+
A user type flows through the derivation and encoding pipeline as follows:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
User type (e.g., case class Person)
|
|
91
|
+
↓
|
|
92
|
+
Schema.derived (automatic via macro)
|
|
93
|
+
↓
|
|
94
|
+
Schema[Person].derive(MessagePackFormat) → MessagePackCodec[Person]
|
|
95
|
+
↓
|
|
96
|
+
Use codec.encode(person) to serialize → Array[Byte]
|
|
97
|
+
Use codec.decode(bytes) to deserialize → Either[SchemaError, Person]
|
|
98
|
+
↓
|
|
99
|
+
Handle SchemaError with location trace on failure
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Type Relationships
|
|
103
|
+
|
|
104
|
+
- **`MessagePackCodec[A]`** — Main public API; contains encoder and decoder for bidirectional serialization
|
|
105
|
+
- **`MessagePackCodecDeriver`** — Configuration and derivation system; generates codecs from Schema
|
|
106
|
+
- **`MessagePackFormat`** — Integration with ZIO Schema format system; enables `Schema[A].derive(MessagePackFormat)`
|
|
107
|
+
- **`MessagePackReader`** — Low-level binary parsing; stateful format-aware decoder
|
|
108
|
+
- **`MessagePackWriter`** — Low-level binary encoding; optimized format-aware encoder
|
|
109
|
+
- **`SchemaError`** — Error type with location traces; renders as paths like `.field[0].nested`
|
|
110
|
+
|
|
111
|
+
## Common Patterns
|
|
112
|
+
|
|
113
|
+
This section shows practical patterns for working with MessagePack codecs in real-world scenarios.
|
|
114
|
+
|
|
115
|
+
### Pattern 1: Derive and Encode a Simple Record
|
|
116
|
+
|
|
117
|
+
To derive and use a MessagePack codec for a record type:
|
|
118
|
+
|
|
119
|
+
```scala
|
|
120
|
+
import zio.blocks.schema._
|
|
121
|
+
import zio.blocks.schema.msgpack._
|
|
122
|
+
|
|
123
|
+
case class Person(name: String, age: Int, email: String)
|
|
124
|
+
|
|
125
|
+
object Person {
|
|
126
|
+
implicit val schema: Schema[Person] = Schema.derived
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
val codec = Person.schema.derive(MessagePackFormat)
|
|
130
|
+
val person = Person("Alice", 30, "alice@example.com")
|
|
131
|
+
val bytes = codec.encode(person)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Pattern 2: Decode MessagePack with Error Handling
|
|
135
|
+
|
|
136
|
+
When decoding MessagePack data, errors include location traces showing where the problem occurred.
|
|
137
|
+
|
|
138
|
+
To decode bytes and handle errors with location information:
|
|
139
|
+
|
|
140
|
+
```scala
|
|
141
|
+
import zio.blocks.schema._
|
|
142
|
+
import zio.blocks.schema.msgpack._
|
|
143
|
+
|
|
144
|
+
case class Employee(id: Int, name: String, salary: Double)
|
|
145
|
+
|
|
146
|
+
object Employee {
|
|
147
|
+
implicit val schema: Schema[Employee] = Schema.derived
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
val codec = Employee.schema.derive(MessagePackFormat)
|
|
151
|
+
val bytes = Array[Byte](1, 2, 3) // truncated data
|
|
152
|
+
|
|
153
|
+
val result = codec.decode(bytes)
|
|
154
|
+
|
|
155
|
+
result match {
|
|
156
|
+
case Right(employee) => println(s"Decoded: $employee")
|
|
157
|
+
case Left(error) =>
|
|
158
|
+
println(s"Error: ${error.getMessage}")
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Pattern 3: Stream Large Datasets with Reader Pool
|
|
163
|
+
|
|
164
|
+
The reader pool efficiently handles streaming decoding of multiple messages from a large dataset.
|
|
165
|
+
|
|
166
|
+
To decode a sequence of values from a stream with pooled readers:
|
|
167
|
+
|
|
168
|
+
```scala
|
|
169
|
+
import zio.blocks.schema._
|
|
170
|
+
import zio.blocks.schema.msgpack._
|
|
171
|
+
|
|
172
|
+
case class Event(id: Long, timestamp: Long, action: String)
|
|
173
|
+
|
|
174
|
+
object Event {
|
|
175
|
+
implicit val schema: Schema[Event] = Schema.derived
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
val codec = Event.schema.derive(MessagePackFormat)
|
|
179
|
+
// Encode an event to get sample bytes
|
|
180
|
+
val event1 = Event(1L, System.currentTimeMillis(), "click")
|
|
181
|
+
val bytes1 = codec.encode(event1)
|
|
182
|
+
|
|
183
|
+
// Decode the bytes back to an event
|
|
184
|
+
val result = codec.decode(bytes1)
|
|
185
|
+
result match {
|
|
186
|
+
case Right(decoded) => println(s"Decoded: $decoded")
|
|
187
|
+
case Left(error) => println(s"Error: ${error.getMessage}")
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Pattern 4: Handle Recursive Types
|
|
192
|
+
|
|
193
|
+
Recursive types (types that reference themselves) are fully supported with automatic cycle detection.
|
|
194
|
+
|
|
195
|
+
To define and encode a recursive data structure:
|
|
196
|
+
|
|
197
|
+
```scala
|
|
198
|
+
import zio.blocks.schema._
|
|
199
|
+
import zio.blocks.schema.msgpack._
|
|
200
|
+
|
|
201
|
+
sealed trait Node
|
|
202
|
+
case class Leaf(value: String) extends Node
|
|
203
|
+
case class Branch(left: Node, right: Node) extends Node
|
|
204
|
+
|
|
205
|
+
object Node {
|
|
206
|
+
implicit val schema: Schema[Node] = Schema.derived
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
val codec = Node.schema.derive(MessagePackFormat)
|
|
210
|
+
val tree: Node = Branch(Leaf("A"), Branch(Leaf("B"), Leaf("C")))
|
|
211
|
+
val bytes = codec.encode(tree)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## MessagePackCodec[A]
|
|
217
|
+
|
|
218
|
+
Main codec type for encoding and decoding values to and from MessagePack binary format. Contains encoder and decoder for bidirectional serialization.
|
|
219
|
+
|
|
220
|
+
### Overview
|
|
221
|
+
|
|
222
|
+
`MessagePackCodec[A]` holds both an encoder and decoder, providing a complete solution for serializing and deserializing values in MessagePack binary format. The codec is derived automatically from a `Schema[A]` using `MessagePackFormat`.
|
|
223
|
+
|
|
224
|
+
### Encoding Values to Byte Array
|
|
225
|
+
|
|
226
|
+
Use the codec to convert values to byte arrays:
|
|
227
|
+
|
|
228
|
+
```scala
|
|
229
|
+
import zio.blocks.schema._
|
|
230
|
+
import zio.blocks.schema.msgpack._
|
|
231
|
+
|
|
232
|
+
case class Product(name: String, price: Double)
|
|
233
|
+
|
|
234
|
+
object Product {
|
|
235
|
+
implicit val schema: Schema[Product] = Schema.derived
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
val codec = Product.schema.derive(MessagePackFormat)
|
|
239
|
+
val product = Product("Widget", 9.99)
|
|
240
|
+
val bytes = codec.encode(product)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Encoding Values to ByteBuffer
|
|
244
|
+
|
|
245
|
+
Write encoded values directly to a ByteBuffer:
|
|
246
|
+
|
|
247
|
+
```scala
|
|
248
|
+
import zio.blocks.schema._
|
|
249
|
+
import zio.blocks.schema.msgpack._
|
|
250
|
+
import java.nio.ByteBuffer
|
|
251
|
+
|
|
252
|
+
case class Item(name: String, quantity: Int)
|
|
253
|
+
|
|
254
|
+
object Item {
|
|
255
|
+
implicit val schema: Schema[Item] = Schema.derived
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
val codec = Item.schema.derive(MessagePackFormat)
|
|
259
|
+
val item = Item("Gadget", 42)
|
|
260
|
+
val buffer = ByteBuffer.allocate(256)
|
|
261
|
+
codec.encode(item, buffer)
|
|
262
|
+
val bytes = java.util.Arrays.copyOf(buffer.array(), buffer.position())
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Decoding Values from Byte Array
|
|
266
|
+
|
|
267
|
+
Use the codec to convert byte arrays back to values:
|
|
268
|
+
|
|
269
|
+
```scala
|
|
270
|
+
import zio.blocks.schema._
|
|
271
|
+
import zio.blocks.schema.msgpack._
|
|
272
|
+
|
|
273
|
+
case class Record(id: Int, value: String)
|
|
274
|
+
|
|
275
|
+
object Record {
|
|
276
|
+
implicit val schema: Schema[Record] = Schema.derived
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
val codec = Record.schema.derive(MessagePackFormat)
|
|
280
|
+
// In real usage, you would have encoded bytes from a previous encoding or external source
|
|
281
|
+
val record = Record(123, "test value")
|
|
282
|
+
val buffer = java.nio.ByteBuffer.allocate(256)
|
|
283
|
+
codec.encode(record, buffer)
|
|
284
|
+
buffer.flip()
|
|
285
|
+
val bytes = new Array[Byte](buffer.remaining())
|
|
286
|
+
buffer.get(bytes)
|
|
287
|
+
|
|
288
|
+
val result: Either[zio.blocks.schema.SchemaError, Record] = codec.decode(bytes)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Decoding Values from ByteBuffer
|
|
292
|
+
|
|
293
|
+
Read and decode values from a ByteBuffer:
|
|
294
|
+
|
|
295
|
+
```scala
|
|
296
|
+
import zio.blocks.schema._
|
|
297
|
+
import zio.blocks.schema.msgpack._
|
|
298
|
+
import java.nio.ByteBuffer
|
|
299
|
+
|
|
300
|
+
case class Data(timestamp: Long, payload: String)
|
|
301
|
+
|
|
302
|
+
object Data {
|
|
303
|
+
implicit val schema: Schema[Data] = Schema.derived
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
val codec = Data.schema.derive(MessagePackFormat)
|
|
307
|
+
// Encode a value first
|
|
308
|
+
val sampleData = Data(System.currentTimeMillis(), "example")
|
|
309
|
+
val encBuffer = ByteBuffer.allocate(256)
|
|
310
|
+
codec.encode(sampleData, encBuffer)
|
|
311
|
+
encBuffer.flip()
|
|
312
|
+
// Then decode from the buffer
|
|
313
|
+
val result = codec.decode(encBuffer)
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## MessagePackCodecDeriver
|
|
319
|
+
|
|
320
|
+
Configuration and derivation system for creating `MessagePackCodec[A]` instances from `Schema[A]`.
|
|
321
|
+
|
|
322
|
+
### Overview
|
|
323
|
+
|
|
324
|
+
`MessagePackCodecDeriver` implements the schema-driven derivation of MessagePack codecs. It automatically handles 27 primitive types and complex types (records, variants, sequences, maps), generating appropriate MessagePack encoders and decoders.
|
|
325
|
+
|
|
326
|
+
### How Derivation Works
|
|
327
|
+
|
|
328
|
+
To create a codec from a schema:
|
|
329
|
+
|
|
330
|
+
```scala
|
|
331
|
+
import zio.blocks.schema._
|
|
332
|
+
import zio.blocks.schema.msgpack._
|
|
333
|
+
|
|
334
|
+
case class Person(name: String, age: Int)
|
|
335
|
+
|
|
336
|
+
object Person {
|
|
337
|
+
implicit val schema: Schema[Person] = Schema.derived
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
val codec = Person.schema.derive(MessagePackFormat)
|
|
341
|
+
// codec: MessagePackCodec[Person] = zio.blocks.schema.msgpack.MessagePackCodecDeriver$$anon$3@7752c755
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
### Primitive Type Support
|
|
345
|
+
|
|
346
|
+
All 27 ZIO Schema primitives are supported:
|
|
347
|
+
- Numeric: `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `BigInt`, `BigDecimal`
|
|
348
|
+
- Logical: `Boolean`, `Char`, `String`
|
|
349
|
+
- Temporal: `Instant`, `LocalDate`, `LocalDateTime`, `LocalTime`, `Duration`, `Period`, `Year`, `YearMonth`, `MonthDay`, `Month`, `DayOfWeek`, `ZonedDateTime`, `OffsetDateTime`, `OffsetTime`, `ZoneId`, `ZoneOffset`
|
|
350
|
+
- Special: `UUID`, `Currency`, `Unit`
|
|
351
|
+
|
|
352
|
+
### Record Type Support
|
|
353
|
+
|
|
354
|
+
Case classes (records) are fully supported. Each field becomes a named key in the MessagePack map encoding:
|
|
355
|
+
|
|
356
|
+
```scala
|
|
357
|
+
import zio.blocks.schema._
|
|
358
|
+
import zio.blocks.schema.msgpack._
|
|
359
|
+
|
|
360
|
+
case class Address(street: String, city: String, zip: String)
|
|
361
|
+
|
|
362
|
+
object Address {
|
|
363
|
+
implicit val schema: Schema[Address] = Schema.derived
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
val codec = Address.schema.derive(MessagePackFormat)
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Variant Type Support
|
|
370
|
+
|
|
371
|
+
Sealed traits and sum types are encoded as MessagePack maps with discriminator fields:
|
|
372
|
+
|
|
373
|
+
```scala
|
|
374
|
+
import zio.blocks.schema._
|
|
375
|
+
import zio.blocks.schema.msgpack._
|
|
376
|
+
|
|
377
|
+
sealed trait Status
|
|
378
|
+
case class Active(since: String) extends Status
|
|
379
|
+
case class Inactive(reason: String) extends Status
|
|
380
|
+
|
|
381
|
+
object Status {
|
|
382
|
+
implicit val schema: Schema[Status] = Schema.derived
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
val codec = Status.schema.derive(MessagePackFormat)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## MessagePackFormat
|
|
391
|
+
|
|
392
|
+
Integration point with ZIO Schema's format system. Provides `BinaryFormat[MessagePackCodec]` to enable `Schema[A].derive(MessagePackFormat)` for any supported type.
|
|
393
|
+
|
|
394
|
+
### Using MessagePackFormat
|
|
395
|
+
|
|
396
|
+
To derive a MessagePack codec using the standard format:
|
|
397
|
+
|
|
398
|
+
```scala
|
|
399
|
+
import zio.blocks.schema._
|
|
400
|
+
import zio.blocks.schema.msgpack._
|
|
401
|
+
|
|
402
|
+
case class Sensor(id: Long, temperature: Double, humidity: Float)
|
|
403
|
+
|
|
404
|
+
object Sensor {
|
|
405
|
+
implicit val schema: Schema[Sensor] = Schema.derived
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
val codec = Sensor.schema.derive(MessagePackFormat)
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
`MessagePackFormat` is a singleton object extending `BinaryFormat[MessagePackCodec]` with the MIME type `"application/msgpack"` and the `MessagePackCodecDeriver` as its derivation strategy.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## MessagePackReader
|
|
416
|
+
|
|
417
|
+
Low-level binary parser implementing MessagePack format with type-specific optimizations and pooling support.
|
|
418
|
+
|
|
419
|
+
### Overview
|
|
420
|
+
|
|
421
|
+
`MessagePackReader` provides stateful reading of MessagePack-encoded data with automatic format detection and efficient handling of all MessagePack types (fixint, fixarray, fixmap, ext, string, binary, float, etc.).
|
|
422
|
+
|
|
423
|
+
### Reading Primitives
|
|
424
|
+
|
|
425
|
+
To read individual values from a MessagePack-encoded byte array:
|
|
426
|
+
|
|
427
|
+
```scala
|
|
428
|
+
import zio.blocks.schema.msgpack._
|
|
429
|
+
import zio.blocks.schema._
|
|
430
|
+
|
|
431
|
+
val bytes = Array[Byte](42) // MessagePack-encoded integer
|
|
432
|
+
|
|
433
|
+
// Use the codec API for public access to decoding
|
|
434
|
+
case class Value(data: Int)
|
|
435
|
+
object Value {
|
|
436
|
+
implicit val schema: Schema[Value] = Schema.derived
|
|
437
|
+
}
|
|
438
|
+
val codec = Value.schema.derive(MessagePackFormat)
|
|
439
|
+
val result = codec.decode(bytes)
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
---
|
|
443
|
+
|
|
444
|
+
## MessagePackWriter
|
|
445
|
+
|
|
446
|
+
Low-level binary encoder implementing MessagePack format with optimizations for compact representation.
|
|
447
|
+
|
|
448
|
+
### Overview
|
|
449
|
+
|
|
450
|
+
`MessagePackWriter` provides efficient writing of Scala values into MessagePack binary format with automatic selection of compact encodings (fixint, fixarray, fixmap, etc.).
|
|
451
|
+
|
|
452
|
+
### Writing Primitives
|
|
453
|
+
|
|
454
|
+
To write individual values to MessagePack format:
|
|
455
|
+
|
|
456
|
+
```scala
|
|
457
|
+
import zio.blocks.schema._
|
|
458
|
+
import zio.blocks.schema.msgpack._
|
|
459
|
+
import java.io.ByteArrayOutputStream
|
|
460
|
+
|
|
461
|
+
// Use the codec API for public access to encoding
|
|
462
|
+
case class Value(data: Int)
|
|
463
|
+
object Value {
|
|
464
|
+
implicit val schema: Schema[Value] = Schema.derived
|
|
465
|
+
}
|
|
466
|
+
val codec = Value.schema.derive(MessagePackFormat)
|
|
467
|
+
val value = Value(42)
|
|
468
|
+
|
|
469
|
+
// MessagePackCodec.encode returns Array[Byte] directly
|
|
470
|
+
val bytes = codec.encode(value)
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
475
|
+
## Error Handling
|
|
476
|
+
|
|
477
|
+
MessagePack decoding errors include location traces showing the path through nested structures where the error occurred.
|
|
478
|
+
|
|
479
|
+
### Understanding Error Traces
|
|
480
|
+
|
|
481
|
+
Errors render as paths like `.field[0].nested.value` showing exactly where decoding failed:
|
|
482
|
+
|
|
483
|
+
```scala
|
|
484
|
+
import zio.blocks.schema._
|
|
485
|
+
import zio.blocks.schema.msgpack._
|
|
486
|
+
|
|
487
|
+
case class Contact(emails: Seq[String])
|
|
488
|
+
|
|
489
|
+
object Contact {
|
|
490
|
+
implicit val schema: Schema[Contact] = Schema.derived
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
val codec = Contact.schema.derive(MessagePackFormat)
|
|
494
|
+
// Example invalid bytes - in real code, this might come from untrusted input
|
|
495
|
+
val invalidBytes: Array[Byte] = Array(0xFF.toByte, 0xFF.toByte) // Invalid MessagePack data
|
|
496
|
+
|
|
497
|
+
val result = codec.decode(invalidBytes)
|
|
498
|
+
|
|
499
|
+
result match {
|
|
500
|
+
case Right(contact) => println(s"Success: $contact")
|
|
501
|
+
case Left(error) =>
|
|
502
|
+
println(s"Error: ${error.getMessage}")
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### Zero-Overhead Error Handling
|
|
507
|
+
|
|
508
|
+
Errors use zero-overhead exceptions (no stack traces) for efficient error reporting in streaming scenarios where errors are expected and handled inline.
|