@zio.dev/zio-blocks 0.0.25 → 0.0.27

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/index.md CHANGED
@@ -81,14 +81,14 @@ val thriftCodec = Schema[Person].derive(ThriftFormat) // Thrift
81
81
  ### Installation
82
82
 
83
83
  ```scala
84
- libraryDependencies += "dev.zio" %% "zio-blocks-schema" % "0.0.25"
84
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema" % "0.0.27"
85
85
 
86
86
  // Optional format modules:
87
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "0.0.25"
88
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "0.0.25"
89
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "0.0.25"
90
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "0.0.25"
91
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "0.0.25"
87
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "0.0.27"
88
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "0.0.27"
89
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "0.0.27"
90
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "0.0.27"
91
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "0.0.27"
92
92
  ```
93
93
 
94
94
  ### Example: Optics
@@ -143,7 +143,7 @@ Chunk is designed for:
143
143
  ### Installation
144
144
 
145
145
  ```scala
146
- libraryDependencies += "dev.zio" %% "zio-blocks-chunk" % "0.0.25"
146
+ libraryDependencies += "dev.zio" %% "zio-blocks-chunk" % "0.0.27"
147
147
  ```
148
148
 
149
149
  ### Example
@@ -227,11 +227,12 @@ Scope.global.scoped { scope =>
227
227
  - **Built-in Dependency Injection**: Wire up your application with `Resource.from[T](wires*)` for automatic constructor-based DI.
228
228
  - **AutoCloseable Integration**: Resources implementing `AutoCloseable` have `close()` registered automatically.
229
229
  - **Unscoped Constraint**: The `scoped` method requires `Unscoped[A]` evidence on the return type, ensuring only pure data (not resources or closures) can escape.
230
+ - **Actionable Runtime Errors**: If a scope reference escapes and is used after closing, `allocate`, `open()`, and `$` throw `IllegalStateException` with a detailed message explaining what went wrong, the common causes, and how to fix it—no silent null returns.
230
231
 
231
232
  ### Installation
232
233
 
233
234
  ```scala
234
- libraryDependencies += "dev.zio" %% "zio-blocks-scope" % "0.0.25"
235
+ libraryDependencies += "dev.zio" %% "zio-blocks-scope" % "0.0.27"
235
236
  ```
236
237
 
237
238
  ### Example: Basic Resource Management
@@ -334,7 +335,7 @@ Generating documentation, README files, or any Markdown content programmatically
334
335
  ### Installation
335
336
 
336
337
  ```scala
337
- libraryDependencies += "dev.zio" %% "zio-blocks-docs" % "0.0.25"
338
+ libraryDependencies += "dev.zio" %% "zio-blocks-docs" % "0.0.27"
338
339
  ```
339
340
 
340
341
  ### Example
@@ -418,7 +419,7 @@ Compile-time type identity with rich metadata. TypeId captures comprehensive inf
418
419
  ### Installation
419
420
 
420
421
  ```scala
421
- libraryDependencies += "dev.zio" %% "zio-blocks-typeid" % "0.0.25"
422
+ libraryDependencies += "dev.zio" %% "zio-blocks-typeid" % "0.0.27"
422
423
  ```
423
424
 
424
425
  ### Example
@@ -461,7 +462,7 @@ A type-indexed heterogeneous collection that stores values by their types with c
461
462
  ### Installation
462
463
 
463
464
  ```scala
464
- libraryDependencies += "dev.zio" %% "zio-blocks-context" % "0.0.25"
465
+ libraryDependencies += "dev.zio" %% "zio-blocks-context" % "0.0.27"
465
466
  ```
466
467
 
467
468
  ### Example
@@ -557,6 +558,7 @@ ZIO Blocks supports **Scala 2.13** and **Scala 3.x** with full source compatibil
557
558
  ### Data Operations
558
559
 
559
560
  - [Patching](./reference/patch.md) - Serializable data transformations
561
+ - [SchemaError](./reference/schema-error.md) - Structured error type for schema operations
560
562
  - [Validation](./reference/validation.md) - Data validation and error handling
561
563
  - [Schema Evolution](./reference/schema-evolution.md) - Migration and compatibility
562
564
 
@@ -571,6 +573,7 @@ ZIO Blocks supports **Scala 2.13** and **Scala 3.x** with full source compatibil
571
573
 
572
574
  ### Guides
573
575
 
576
+ - [Migrating from ZIO Schema](./guides/zio-schema-migration.md) - Step-by-step guide to migrating from ZIO Schema 1.x to ZIO Blocks Schema
574
577
  - [Query DSL Part 1: Expressions](./guides/query-dsl-reified-optics.md) - Build type-safe, composable query expressions
575
578
  - [Query DSL Part 2: SQL Generation](./guides/query-dsl-sql.md) - Translate query expressions into SQL
576
579
  - [Query DSL Part 3: Extending the Expression Language](./guides/query-dsl-extending.md) - Add custom operators beyond SchemaExpr
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@zio.dev/zio-blocks",
3
3
  "description": "ZIO Blocks Documentation",
4
4
  "license": "Apache-2.0",
5
- "version": "0.0.25",
5
+ "version": "0.0.27",
6
6
  "repository": {
7
7
  "url": "https://github.com/zio/zio-blocks"
8
8
  }
@@ -0,0 +1,352 @@
1
+ ---
2
+ id: allows
3
+ title: "Allows"
4
+ ---
5
+
6
+ `Allows[A, S]` is a compile-time capability token that proves, at the call site, that type `A` satisfies the structural grammar `S`.
7
+
8
+ `Allows` does **not** require or use `Schema[A]`. It inspects the Scala type structure of `A` directly at compile time, using nothing but the Scala type system. Any `Schema[A]` that appears alongside `Allows` in examples is the library author's own separate constraint — it is not imposed by `Allows` itself.
9
+
10
+ ## Motivation
11
+
12
+ ZIO Blocks (ZIO Schema 2) gives library authors a powerful way to build data-oriented DSLs. A library can accept `A: Schema` and use the schema at runtime to serialize, deserialize, query, or transform values of `A`. But `Allows` is useful even without a Schema — it can enforce structural preconditions on *any* generic function.
13
+
14
+ The gap is **structural preconditions**. Many generic functions only make sense for a subset of types:
15
+
16
+ - A CSV serializer requires flat records of scalars.
17
+ - An RDBMS layer cannot handle nested records as column values.
18
+ - An event bus expects a sealed trait of flat record cases.
19
+ - A JSON document store allows arbitrarily nested records but not `DynamicValue` leaves.
20
+
21
+ Today, these constraints can only be checked at runtime, producing confusing errors deep inside library internals.
22
+
23
+ `Allows[A, S]` closes this gap: the constraint is verified at the **call site**, at compile time, with precise, path-aware error messages and concrete fix suggestions.
24
+
25
+ ## The Upper Bound Semantics
26
+
27
+ `Allows[A, S]` is an upper bound. A type `A` that uses only a strict subset of what `S` permits also satisfies it — just as `A <: Foo` does not require that `A` uses every method of `Foo`.
28
+
29
+ ```scala
30
+ // Allows[UserRow, Record[Primitive | Optional[Primitive]]] is satisfied even if
31
+ // UserRow has no Option fields — the Optional branch is simply never needed.
32
+ ```
33
+
34
+ ## Grammar Nodes
35
+
36
+ All grammar nodes extend `Allows.Structural`.
37
+
38
+ | Node | Matches |
39
+ |---|---|
40
+ | `Primitive` | **Any** scalar — catch-all for all 30 Schema 2 primitive types |
41
+ | `Primitive.Boolean` | `scala.Boolean` only |
42
+ | `Primitive.Int` | `scala.Int` only |
43
+ | `Primitive.Long` | `scala.Long` only |
44
+ | `Primitive.Double` | `scala.Double` only |
45
+ | `Primitive.Float` | `scala.Float` only |
46
+ | `Primitive.String` | `java.lang.String` only |
47
+ | `Primitive.BigDecimal` | `scala.BigDecimal` only |
48
+ | `Primitive.BigInt` | `scala.BigInt` only |
49
+ | `Primitive.Unit` | `scala.Unit` only |
50
+ | `Primitive.Byte` | `scala.Byte` only |
51
+ | `Primitive.Short` | `scala.Short` only |
52
+ | `Primitive.Char` | `scala.Char` only |
53
+ | `Primitive.UUID` | `java.util.UUID` only |
54
+ | `Primitive.Currency` | `java.util.Currency` only |
55
+ | `Primitive.Instant` / `LocalDate` / `LocalDateTime` / … | Each specific `java.time.*` type |
56
+ | `Record[A]` | A case class / product type whose every field satisfies `A`. Vacuously true for zero-field records. Sealed traits and enums are **automatically unwrapped**: each case is checked individually, so no `Variant` node is needed. |
57
+ | `Sequence[A]` | `List`, `Vector`, `Set`, `Array`, `Chunk`, … whose element type satisfies `A` |
58
+ | `Map[K, V]` | `Map`, `HashMap`, … whose key satisfies `K` and value satisfies `V` |
59
+ | `Optional[A]` | `Option[X]` where the inner type `X` satisfies `A` |
60
+ | `Wrapped[A]` | A ZIO Prelude `Newtype`/`Subtype` wrapper whose underlying type satisfies `A` |
61
+ | `Dynamic` | `DynamicValue` — the schema-less escape hatch |
62
+ | `Self` | Recursive self-reference back to the entire enclosing `Allows[A, S]` grammar |
63
+ | `` `\|` `` | Union of two grammar nodes: `A \| B`. In Scala 2 write `` A `\|` B `` in infix position. |
64
+
65
+ Every specific `Primitive.Xxx` node also satisfies the catch-all `Primitive`. This means a type annotated with `Primitive.Int` is valid wherever `Primitive` or `Primitive | Primitive.Long` is required.
66
+
67
+ ## Specific Primitives
68
+
69
+ The `Primitive` parent class is the catch-all: it accepts any of the 30 Schema 2 primitive types. For stricter control — such as when the target serialisation format only supports a subset — use the specific subtype nodes in `Allows.Primitive`:
70
+
71
+ ```scala
72
+ import zio.blocks.schema.comptime.Allows
73
+ import Allows._
74
+
75
+ // Only JSON-representable scalars (no UUID, Char, java.time.*)
76
+ type JsonPrimitive =
77
+ Primitive.Boolean | Primitive.Int | Primitive.Long |
78
+ Primitive.Double | Primitive.String | Primitive.BigDecimal |
79
+ Primitive.BigInt | Primitive.Unit
80
+
81
+ def toJson[A](doc: A)(using Allows[A, Record[JsonPrimitive | Self]]): String = ???
82
+
83
+ // Only numeric types
84
+ type Numeric = Primitive.Int | Primitive.Long | Primitive.Double | Primitive.Float |
85
+ Primitive.BigInt | Primitive.BigDecimal
86
+
87
+ def aggregate[A](data: A)(using Allows[A, Record[Numeric]]): Double = ???
88
+ ```
89
+
90
+ A type annotated with `Primitive.Int` satisfies `Primitive` (the catch-all) because `Primitive.Int extends Primitive`:
91
+
92
+ ```scala
93
+ import zio.blocks.schema.comptime.Allows
94
+ import Allows._
95
+
96
+ val ev: Allows[Int, Primitive] = implicitly // Primitive (catch-all) — ✓
97
+ val sp: Allows[Int, Primitive.Int] = implicitly // Primitive.Int (specific) — ✓
98
+ ```
99
+
100
+ ### JSON Document Store Example
101
+
102
+ JSON's primitive value set is `null | boolean | number | string`. Types such as `UUID`, `Char`, and all `java.time.*` types have no native JSON representation and must be encoded as strings at the application layer. Using `JsonPrimitive` instead of the catch-all `Primitive` enforces this at compile time.
103
+
104
+ A JSON document grammar is straightforward: a JSON value is either a record (JSON object) or a sequence (JSON array), and `Self` handles all nesting:
105
+
106
+ ```scala
107
+ import zio.blocks.schema.comptime.Allows
108
+ import Allows._
109
+
110
+ type JsonPrimitive =
111
+ Primitive.Boolean | Primitive.Int | Primitive.Long | Primitive.Double |
112
+ Primitive.String | Primitive.BigDecimal | Primitive.BigInt | Primitive.Unit
113
+
114
+ type Json = Record[JsonPrimitive | Self] | Sequence[JsonPrimitive | Self]
115
+
116
+ def toJson[A](doc: A)(using Allows[A, Json]): String = ???
117
+ ```
118
+
119
+ `Self` recurses back to `Json` at every nested position, so `List[String]` satisfies `Sequence[JsonPrimitive | Self]` (String is JsonPrimitive), `List[Author]` satisfies it too (Author satisfies `Record[JsonPrimitive | Self]` via Self), and top-level arrays work directly.
120
+
121
+ A type with a UUID or Instant field fails at compile time:
122
+
123
+ ```
124
+ [error] Schema shape violation at WithUUID.id: found Primitive(java.util.UUID),
125
+ required Primitive.Boolean | Primitive.Int | ... | Primitive.String | ...
126
+ UUID is not a JSON-native type — encode it as Primitive.String.
127
+ ```
128
+
129
+ ## Union Syntax
130
+
131
+ Union types express "or" in the grammar.
132
+
133
+ **Scala 3** uses native union type syntax:
134
+
135
+ ```scala
136
+ import zio.blocks.schema.comptime.Allows
137
+ import Allows._
138
+
139
+ def writeCsv[A](rows: Seq[A])(using
140
+ Allows[A, Record[Primitive | Optional[Primitive]]]
141
+ ): Unit = ???
142
+ ```
143
+
144
+ **Scala 2** uses the `` `\|` `` infix operator from `Allows`:
145
+
146
+ ```scala
147
+ import zio.blocks.schema.comptime.Allows
148
+ import Allows._
149
+
150
+ def writeCsv[A](rows: Seq[A])(implicit
151
+ ev: Allows[A, Record[Primitive | Optional[Primitive]]]
152
+ ): Unit = ???
153
+ ```
154
+
155
+ Both spellings compile and produce the same semantic behavior. The grammar is identical — the only difference is how the union type is expressed.
156
+
157
+ ## Use Cases
158
+
159
+ ### Flat Record (CSV, RDBMS Row)
160
+
161
+ ```scala
162
+ import zio.blocks.schema.Schema
163
+ import zio.blocks.schema.comptime.Allows
164
+ import Allows._
165
+
166
+ // Flat record: only primitives and optional primitives allowed
167
+ def writeCsv[A: Schema](rows: Seq[A])(using
168
+ Allows[A, Record[Primitive | Optional[Primitive]]]
169
+ ): Unit = ???
170
+
171
+ // RDBMS INSERT: primitives, optional primitives, or string-keyed maps (JSONB)
172
+ def insert[A: Schema](value: A)(using
173
+ Allows[A, Record[Primitive | Optional[Primitive] | Allows.Map[Primitive, Primitive]]]
174
+ ): String = ???
175
+ ```
176
+
177
+ If a user passes a type with nested records, they get a precise compile-time error:
178
+
179
+ ```
180
+ [error] Schema shape violation at UserWithAddress.address: found Record(Address),
181
+ required Primitive | Optional[Primitive] | Map[Primitive, Primitive]
182
+ ```
183
+
184
+ ### Event Bus / Message Broker
185
+
186
+ Published events are typically sealed traits of flat record cases. No `Variant` node is needed — sealed traits are automatically unwrapped:
187
+
188
+ ```scala
189
+ import zio.blocks.schema.Schema
190
+ import zio.blocks.schema.comptime.Allows
191
+ import Allows._
192
+
193
+ // DomainEvent is a sealed trait; its cases must each satisfy Record[Primitive | Sequence[Primitive]]
194
+ def publish[A: Schema](event: A)(using
195
+ Allows[A, Record[Primitive | Optional[Primitive] | Sequence[Primitive]]]
196
+ ): Unit = ???
197
+ ```
198
+
199
+ If a case of the sealed trait has a nested record field, the error names that case and field:
200
+
201
+ ```
202
+ [error] Schema shape violation at DomainEvent.OrderPlaced.items.<element>:
203
+ found Record(OrderItem), required Primitive | Optional[Primitive] | Sequence[Primitive]
204
+ ```
205
+
206
+ ### JSON Document Store (Recursive)
207
+
208
+ A document store accepts arbitrarily nested records but not `DynamicValue` leaves. The `Self` node expresses the recursive grammar:
209
+
210
+ ```scala
211
+ import zio.blocks.schema.Schema
212
+ import zio.blocks.schema.comptime.Allows
213
+ import Allows._
214
+
215
+ type JsonDocument =
216
+ Record[Primitive | Self | Optional[Primitive | Self] | Sequence[Primitive | Self] | Allows.Map[Primitive, Primitive | Self]]
217
+
218
+ def toJson[A: Schema](doc: A)(implicit ev: Allows[A, JsonDocument]): String = ???
219
+ ```
220
+
221
+ This grammar allows:
222
+ - `case class Author(name: String, email: String)` — Record[Primitive] ✓
223
+ - `case class Book(title: String, author: Author, tags: List[String])` — Record with Self-nested record and Sequence[Primitive] ✓
224
+ - `case class Category(name: String, subcategories: List[Category])` — recursive ✓
225
+
226
+ But rejects:
227
+ - `case class Bad(name: String, payload: DynamicValue)` — DynamicValue is not in the grammar ✗
228
+
229
+ ### GraphQL / Tree Structures (Self)
230
+
231
+ ```scala
232
+ import zio.blocks.schema.Schema
233
+ import zio.blocks.schema.comptime.Allows
234
+ import Allows._
235
+
236
+ def graphqlType[A: Schema]()(using
237
+ Allows[A, Record[Primitive | Optional[Self] | Sequence[Self]]]
238
+ ): String = ???
239
+
240
+ // Works:
241
+ case class TreeNode(value: Int, children: List[TreeNode])
242
+ object TreeNode { implicit val schema: Schema[TreeNode] = Schema.derived }
243
+ // graphqlType[TreeNode]() — compiles fine
244
+ ```
245
+
246
+ ## The `Self` Grammar Node
247
+
248
+ `Self` refers back to the entire enclosing `Allows[A, S]` grammar. It allows the grammar to describe recursive data structures.
249
+
250
+ **Non-recursive types** satisfy `Self`-containing grammars without issue: if no field ever recurses back to the root type, the `Self` position is never reached, and the constraint is vacuously satisfied.
251
+
252
+ **Mutual recursion** between two or more distinct types is a compile-time error:
253
+
254
+ ```
255
+ [error] Mutually recursive types are not supported by Allows.
256
+ Cycle: Forest -> Tree -> Forest
257
+ ```
258
+
259
+ ## `Wrapped[A]` and Newtypes
260
+
261
+ The `Wrapped[A]` node matches ZIO Prelude `Newtype` and `Subtype` wrappers. The underlying type must satisfy `A`.
262
+
263
+ ```scala
264
+ // ZIO Prelude Newtype pattern:
265
+ import zio.prelude.Newtype
266
+ object ProductCode extends Newtype[String]
267
+ type ProductCode = ProductCode.Type
268
+
269
+ given Schema[ProductCode] =
270
+ Schema[String].transform(_.asInstanceOf[ProductCode], _.asInstanceOf[String])
271
+
272
+ // ProductCode satisfies Wrapped[Primitive] — its underlying String is Primitive
273
+ val ev: Allows[ProductCode, Wrapped[Primitive]] = implicitly
274
+ ```
275
+
276
+ **Scala 3 opaque types** are resolved to their underlying type by the macro (they are transparent), so `opaque type UserId = UUID` satisfies `Primitive` (not `Wrapped[Primitive]`):
277
+
278
+ ```scala
279
+ opaque type UserId = java.util.UUID
280
+ // UserId satisfies Allows[UserId, Primitive] — resolved to UUID (a primitive)
281
+ ```
282
+
283
+ ## Sealed Traits and Enums (Auto-Unwrap)
284
+
285
+ Sealed traits and enums are **automatically unwrapped** by the macro. Whenever a sealed type is encountered at any grammar check position, the macro recursively checks every case against the same grammar. This makes a `Variant` grammar node unnecessary.
286
+
287
+ ```scala
288
+ import zio.blocks.schema.comptime.Allows
289
+ import Allows._
290
+
291
+ sealed trait Shape
292
+ case class Circle(radius: Double) extends Shape
293
+ case class Rectangle(width: Double, height: Double) extends Shape
294
+ case object Point extends Shape
295
+
296
+ // No Variant node — Shape is auto-unwrapped, all cases checked against Record[Primitive]
297
+ val ev: Allows[Shape, Record[Primitive]] = implicitly
298
+ ```
299
+
300
+ Auto-unwrap is recursive: if a case is itself a sealed trait, its cases are unwrapped too, to any depth.
301
+
302
+ Union branches (`A | B`) work naturally with auto-unwrap: unused branches are fine under `Allows` upper-bound semantics.
303
+
304
+ ## Error Messages
305
+
306
+ When a type does not satisfy the grammar, the macro reports:
307
+
308
+ 1. **The path** to the violating field: `Order.items.<element>`
309
+ 2. **What was found**: `Record(OrderItem)`
310
+ 3. **What was required**: `Primitive | Sequence[Primitive]`
311
+ 4. **A hint** where applicable
312
+
313
+ Multiple violations are reported in a single compilation pass — the user sees all problems at once.
314
+
315
+ Example:
316
+
317
+ ```
318
+ [error] Schema shape violation at UserWithAddress.address: found Record(Address),
319
+ required Primitive | Optional[Primitive] | Map[Primitive, Primitive]
320
+ [error] Hint: Type 'Address' does not match any allowed shape
321
+ ```
322
+
323
+ ## Singleton / Zero-Field Records
324
+
325
+ `Record[A]` is vacuously true for case objects and zero-field records, since there are no fields to violate the constraint:
326
+
327
+ ```scala
328
+ import zio.blocks.schema.Schema
329
+ import zio.blocks.schema.comptime.Allows
330
+ import Allows._
331
+
332
+ case object EmptyEvent
333
+ implicit val schema: Schema[EmptyEvent.type] = Schema.derived
334
+
335
+ val ev: Allows[EmptyEvent.type, Record[Primitive]] = implicitly // vacuously true
336
+ ```
337
+
338
+ ## Runtime Cost
339
+
340
+ `Allows[A, S]` carries **zero runtime overhead**. The macro emits a reference to a single private singleton `Allows.instance` cast to the required type. There is no per-call-site allocation.
341
+
342
+ ## Scala 2 vs Scala 3
343
+
344
+ | Feature | Scala 2 | Scala 3 |
345
+ |---|---|---|
346
+ | Union syntax | `` A `\|` B `` infix | `A \| B` native union type |
347
+ | Summon syntax | `implicitly[Allows[A, S]]` | `summon[Allows[A, S]]` or `implicitly` |
348
+ | Evidence parameter | `(implicit ev: Allows[A, S])` | `(using Allows[A, S])` |
349
+ | Opaque type detection | ZIO Prelude only | Scala 3 opaque types + ZIO Prelude + neotype |
350
+ | Derivation keyword | `Schema.derived` implicit | `Schema.derived` or `derives Schema` |
351
+
352
+ Both Scala versions produce the same macro behavior and the same error messages.
@@ -32,8 +32,8 @@ case class Person(name: String, age: Int)
32
32
  object Person {
33
33
  // Derive a schema for Person (required for codec derivation)
34
34
  implicit val schema: Schema[Person] = Schema.derived
35
- // Derive a JSON codec from the schema
36
- implicit val codec: JsonBinaryCodec[Person] = schema.derive[JsonFormat.type](JsonFormat)
35
+ // Derive a JSON codec from the schema
36
+ implicit val codec: JsonBinaryCodec[Person] = schema.derive(JsonFormat)
37
37
  }
38
38
 
39
39
  // Encode
@@ -48,23 +48,23 @@ 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.25"
51
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema" % "0.0.27"
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.25"
58
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "0.0.25"
59
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "0.0.25"
60
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "0.0.25"
61
- libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "0.0.25"
57
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-avro" % "0.0.27"
58
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-toon" % "0.0.27"
59
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-messagepack" % "0.0.27"
60
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-thrift" % "0.0.27"
61
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-bson" % "0.0.27"
62
62
  ```
63
63
 
64
64
  For cross-platform projects (Scala.js):
65
65
 
66
66
  ```scala
67
- libraryDependencies += "dev.zio" %%% "zio-blocks-schema" % "0.0.25"
67
+ libraryDependencies += "dev.zio" %%% "zio-blocks-schema" % "0.0.27"
68
68
  ```
69
69
 
70
70
  Supported Scala versions: 2.13.x and 3.x.
@@ -116,7 +116,7 @@ object Person {
116
116
  }
117
117
 
118
118
  // Pass a Format object to get a codec for that format
119
- val jsonCodec: JsonBinaryCodec[Person] = Schema[Person].derive[JsonFormat.type](JsonFormat)
119
+ val jsonCodec: JsonBinaryCodec[Person] = Schema[Person].derive(JsonFormat)
120
120
  ```
121
121
 
122
122
  This works with any format:
package/reference/docs.md CHANGED
@@ -10,7 +10,7 @@ Complete API reference for the zio-blocks-docs module - a zero-dependency GitHub
10
10
  ## Installation
11
11
 
12
12
  ```scala
13
- libraryDependencies += "dev.zio" %% "zio-blocks-docs" % "0.0.25"
13
+ libraryDependencies += "dev.zio" %% "zio-blocks-docs" % "0.0.27"
14
14
  ```
15
15
 
16
16
  ## Core Types
@@ -75,13 +75,13 @@ textAny.matches(html) // true
75
75
  Add the following to your `build.sbt`:
76
76
 
77
77
  ```scala
78
- libraryDependencies += "dev.zio" %% "zio-blocks-mediatype" % "0.0.25"
78
+ libraryDependencies += "dev.zio" %% "zio-blocks-mediatype" % "0.0.27"
79
79
  ```
80
80
 
81
81
  For cross-platform projects (Scala.js):
82
82
 
83
83
  ```scala
84
- libraryDependencies += "dev.zio" %%% "zio-blocks-mediatype" % "0.0.25"
84
+ libraryDependencies += "dev.zio" %%% "zio-blocks-mediatype" % "0.0.27"
85
85
  ```
86
86
 
87
87
  Supported Scala versions: 2.13.x and 3.x.
@@ -38,12 +38,12 @@ object User extends CompanionOptics[User] {
38
38
  .derived[User]
39
39
  .modifier(Modifier.config("db.table-name", "users"))
40
40
 
41
- implicit val jsonCodec: JsonBinaryCodec[User] =
42
- schema
43
- .deriving[JsonBinaryCodec](JsonBinaryCodecDeriver)
44
- .modifier(User.name, Modifier.rename("username"))
45
- .modifier(User.cache, Modifier.transient())
46
- .derive
41
+ implicit val jsonCodec: JsonBinaryCodec[User] =
42
+ schema
43
+ .deriving(JsonBinaryCodecDeriver)
44
+ .modifier(User.name, Modifier.rename("username"))
45
+ .modifier(User.cache, Modifier.transient())
46
+ .derive
47
47
 
48
48
  lazy val id : Lens[User, String] = $(_.id)
49
49
  lazy val name : Lens[User, String] = $(_.name)
@@ -86,9 +86,9 @@ object User extends CompanionOptics[User] {
86
86
  implicit val schema: Schema[User] =
87
87
  Schema.derived[User]
88
88
 
89
- implicit val jsonCodec: JsonBinaryCodec[User] =
90
- schema
91
- .derive[JsonBinaryCodec](JsonBinaryCodecDeriver)
89
+ implicit val jsonCodec: JsonBinaryCodec[User] =
90
+ schema
91
+ .derive(JsonBinaryCodecDeriver)
92
92
  }
93
93
  ```
94
94