@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
|
@@ -26,7 +26,7 @@ val result = data.get(path).one
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
:::tip
|
|
29
|
-
For a practical example of extracting column names from `DynamicOptic` paths to generate SQL, see the [Query DSL Part 2: SQL Generation](
|
|
29
|
+
For a practical example of extracting column names from `DynamicOptic` paths to generate SQL, see the [Query DSL Part 2: SQL Generation](../../guides/query-dsl-sql.md) guide.
|
|
30
30
|
:::
|
|
31
31
|
|
|
32
32
|
## Motivation
|
|
@@ -57,7 +57,7 @@ The relationship between typed and dynamic optics:
|
|
|
57
57
|
└──────────────────┘ └──────────────────┘
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
The `Optic[S, A]` and `DynamicOptic` types serve complementary roles in ZIO Blocks' optics system. `Optic[S, A]` provides compile-time type safety through macros or manual construction, operates on typed Scala values, and can be converted to a `DynamicOptic` via the `optic.toDynamic` method. In contrast, `DynamicOptic` performs runtime type checking and is constructed through a builder API or [path interpolator](
|
|
60
|
+
The `Optic[S, A]` and `DynamicOptic` types serve complementary roles in ZIO Blocks' optics system. `Optic[S, A]` provides compile-time type safety through macros or manual construction, operates on typed Scala values, and can be converted to a `DynamicOptic` via the `optic.toDynamic` method. In contrast, `DynamicOptic` performs runtime type checking and is constructed through a builder API or [path interpolator](./path-interpolator.md), operating directly on [DynamicValue](./dynamic-value.md), [Schema](./schema.md), and [Reflect](./reflect.md) representations.
|
|
61
61
|
|
|
62
62
|
## Design & Structure
|
|
63
63
|
|
|
@@ -157,7 +157,7 @@ Note: `.atKey` and `.atKeys` require an implicit `Schema[K]` to convert the type
|
|
|
157
157
|
|
|
158
158
|
### Path Interpolator
|
|
159
159
|
|
|
160
|
-
The [`p"..."` path interpolator](
|
|
160
|
+
The [`p"..."` path interpolator](./path-interpolator.md) provides a concise compile-time syntax for building
|
|
161
161
|
`DynamicOptic` values:
|
|
162
162
|
|
|
163
163
|
```scala
|
|
@@ -181,7 +181,7 @@ val success = p".result<Success>.value"
|
|
|
181
181
|
val complex = p""".groups[*].members[0].contacts{"email"}"""
|
|
182
182
|
```
|
|
183
183
|
|
|
184
|
-
See [Path Interpolator](
|
|
184
|
+
See [Path Interpolator](./path-interpolator.md) for the full syntax reference.
|
|
185
185
|
|
|
186
186
|
### From Typed Optics
|
|
187
187
|
|
|
@@ -360,7 +360,7 @@ expected Email, but got Push
|
|
|
360
360
|
|
|
361
361
|
`DynamicOptic` provides two string formats for different contexts:
|
|
362
362
|
|
|
363
|
-
- **`toString`** — Compact path syntax matching the [`p"..."` interpolator](
|
|
363
|
+
- **`toString`** — Compact path syntax matching the [`p"..."` interpolator](./path-interpolator.md) format
|
|
364
364
|
- **`toScalaString`** — Scala method call syntax used in error messages
|
|
365
365
|
|
|
366
366
|
| Node | `toString` | `toScalaString` |
|
|
@@ -396,6 +396,152 @@ val serialized: DynamicValue = opticSchema.toDynamicValue(path)
|
|
|
396
396
|
```
|
|
397
397
|
|
|
398
398
|
|
|
399
|
+
## Search Optics
|
|
400
|
+
|
|
401
|
+
A **Search optic** recursively traverses a data structure to find **all occurrences** matching a type or schema. It produces a `Traversal[S, A]` that collects matches in depth-first, left-to-right order.
|
|
402
|
+
|
|
403
|
+
### Motivation
|
|
404
|
+
|
|
405
|
+
Search optics address scenarios where you need to:
|
|
406
|
+
|
|
407
|
+
- **Find all values of a specific type** across deeply nested structures (e.g., all `String` fields in a nested record)
|
|
408
|
+
- **Extract all data matching a structural pattern** (e.g., all records with `{ name: string, age: int }` schema)
|
|
409
|
+
- **Transform all matching occurrences** in untyped or partially-typed data
|
|
410
|
+
- **Query data without knowing the exact path** — the search discovers all paths automatically
|
|
411
|
+
|
|
412
|
+
### Typed API: `.searchFor[T]`
|
|
413
|
+
|
|
414
|
+
Use the `.searchFor[T]` extension method on a `CompanionOptics` to search for all values of type `T`:
|
|
415
|
+
|
|
416
|
+
```scala
|
|
417
|
+
import zio.blocks.schema._
|
|
418
|
+
|
|
419
|
+
case class Person(name: String, age: Int)
|
|
420
|
+
object Person {
|
|
421
|
+
implicit val schema: Schema[Person] = Schema.derived
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
case class Address(city: String)
|
|
425
|
+
object Address {
|
|
426
|
+
implicit val schema: Schema[Address] = Schema.derived
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
case class Company(name: String, employees: List[Person], hq: Address)
|
|
430
|
+
object Company extends CompanionOptics[Company] {
|
|
431
|
+
implicit val schema: Schema[Company] = Schema.derived
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Find all Person instances within a Company
|
|
435
|
+
val personSearch: Traversal[Company, Person] = Company.optic(_.searchFor[Person])
|
|
436
|
+
|
|
437
|
+
val company = Company(
|
|
438
|
+
"Acme",
|
|
439
|
+
List(Person("Alice", 30), Person("Bob", 25)),
|
|
440
|
+
Address("NYC")
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
// Modify all persons (increment their age)
|
|
444
|
+
val updated: Company = personSearch.modify(company, p => p.copy(age = p.age + 1))
|
|
445
|
+
// Company("Acme", List(Person("Alice", 31), Person("Bob", 26)), Address("NYC"))
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Dynamic API: Path Strings with `#` Prefix
|
|
449
|
+
|
|
450
|
+
Use the `#` prefix in path strings to specify type or schema patterns:
|
|
451
|
+
|
|
452
|
+
```scala
|
|
453
|
+
import zio.blocks.schema._
|
|
454
|
+
|
|
455
|
+
val data = DynamicValue.Record(
|
|
456
|
+
"company" -> DynamicValue.Record(
|
|
457
|
+
"name" -> DynamicValue.string("Acme"),
|
|
458
|
+
"employees" -> DynamicValue.Sequence(
|
|
459
|
+
DynamicValue.Record("name" -> DynamicValue.string("Alice")),
|
|
460
|
+
DynamicValue.Record("name" -> DynamicValue.string("Bob"))
|
|
461
|
+
)
|
|
462
|
+
)
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
// Find all strings in the data
|
|
466
|
+
val allStrings = data.get(p"#string").toChunk
|
|
467
|
+
// Chunk(
|
|
468
|
+
// DynamicValue.string("Acme"),
|
|
469
|
+
// DynamicValue.string("Alice"),
|
|
470
|
+
// DynamicValue.string("Bob")
|
|
471
|
+
// )
|
|
472
|
+
|
|
473
|
+
// Find all records matching a schema
|
|
474
|
+
val recordsWithName = data.get(p"#record { name: string }").toChunk
|
|
475
|
+
|
|
476
|
+
// Modify all matching values
|
|
477
|
+
val modified = data.modify(p"#string")(dv =>
|
|
478
|
+
dv match {
|
|
479
|
+
case DynamicValue.Primitive(PrimitiveValue.String(s)) =>
|
|
480
|
+
DynamicValue.string(s.toUpperCase)
|
|
481
|
+
case other => other
|
|
482
|
+
}
|
|
483
|
+
)
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Supported Patterns
|
|
487
|
+
|
|
488
|
+
Search optics support both **type-based** and **schema-based** patterns:
|
|
489
|
+
|
|
490
|
+
| Pattern | Matches | Example |
|
|
491
|
+
|--------------------------------|----------------------------------------|---------------------------|
|
|
492
|
+
| `#Nominal` (type name) | Values of that type name | `#Person` |
|
|
493
|
+
| `#int`, `#string`, `#boolean` | Specific primitive types (case-insensitive) | `#int`, `#string`, `#boolean` |
|
|
494
|
+
| `#record { ... }` | Records with matching fields | `#record { name: string }` |
|
|
495
|
+
| `#variant { ... }` | Variant cases with matching content | `#variant { Error: string }` |
|
|
496
|
+
| `#list(...)` | Lists/sequences with element type | `#list(string)` |
|
|
497
|
+
| `#map(...)` | Maps with key and value types | `#map(string, int)` |
|
|
498
|
+
| `#option(...)` | Optional values with inner type | `#option(int)` |
|
|
499
|
+
|
|
500
|
+
### Traversal Order
|
|
501
|
+
|
|
502
|
+
Results are collected in **depth-first, left-to-right order**:
|
|
503
|
+
|
|
504
|
+
```scala
|
|
505
|
+
import zio.blocks.schema._
|
|
506
|
+
|
|
507
|
+
val nested = DynamicValue.Record(
|
|
508
|
+
"a" -> DynamicValue.int(1),
|
|
509
|
+
"b" -> DynamicValue.Record(
|
|
510
|
+
"c" -> DynamicValue.int(2),
|
|
511
|
+
"d" -> DynamicValue.int(3)
|
|
512
|
+
),
|
|
513
|
+
"e" -> DynamicValue.int(4)
|
|
514
|
+
)
|
|
515
|
+
|
|
516
|
+
// Depth-first, left-to-right: 1, 2, 3, 4
|
|
517
|
+
val allInts = nested.get(p"#int").toChunk
|
|
518
|
+
// Chunk(1, 2, 3, 4)
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Known Limitation: Nominal Matching in Untyped Contexts
|
|
522
|
+
|
|
523
|
+
`Nominal` pattern matching (e.g., `#Person`) returns `false` when applied to `DynamicValue` or `Json` because these untyped structures carry no type identity. To match nominally-typed data, use one of these approaches:
|
|
524
|
+
|
|
525
|
+
- **Use the typed API**: `optic(_.searchFor[Person])`
|
|
526
|
+
- **Or use structural patterns**: `p"#record { name: string, age: int }"`
|
|
527
|
+
|
|
528
|
+
Here's how the two approaches differ in practice:
|
|
529
|
+
|
|
530
|
+
```scala
|
|
531
|
+
import zio.blocks.schema._
|
|
532
|
+
|
|
533
|
+
val dynamicData: DynamicValue = ???
|
|
534
|
+
|
|
535
|
+
// This won't match — no type identity available
|
|
536
|
+
val nominalMatch = dynamicData.get(p"#Person").toChunk
|
|
537
|
+
// Chunk()
|
|
538
|
+
|
|
539
|
+
// This works — structural matching
|
|
540
|
+
val structuralMatch = dynamicData.get(p"#record { name: string, age: int }").toChunk
|
|
541
|
+
// Chunk(...matching records...)
|
|
542
|
+
```
|
|
543
|
+
|
|
399
544
|
## See Also
|
|
400
545
|
|
|
401
546
|
- [DynamicSchema](./dynamic-schema.md) — use `DynamicSchema#get` with a `DynamicOptic` to navigate schema trees and inspect nested type structures.
|
|
547
|
+
- [Optics](./optics.md) — reference page for typed `Optic[S, A]` and reflective optics concepts.
|
|
@@ -41,7 +41,7 @@ DynamicSchema ←── reconstructed from storage
|
|
|
41
41
|
Schema[OrderPlaced] ←── operational again, can encode and decode
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
This pattern enables schema registries: the Checkout Service registers its event schema on startup; the Fulfillment Service fetches it and rebinds it against its own type definitions, guaranteeing it uses the exact schema that was in effect when the event was encoded. See [BindingResolver](
|
|
44
|
+
This pattern enables schema registries: the Checkout Service registers its event schema on startup; the Fulfillment Service fetches it and rebinds it against its own type definitions, guaranteeing it uses the exact schema that was in effect when the event was encoded. See [BindingResolver](binding-resolver.md) for the complete rebinding API.
|
|
45
45
|
|
|
46
46
|
## Creating a DynamicSchema
|
|
47
47
|
|
|
@@ -83,7 +83,7 @@ dynamic
|
|
|
83
83
|
// value = Primitive(
|
|
84
84
|
// primitiveType = String(None),
|
|
85
85
|
// typeId = String,
|
|
86
|
-
// primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@
|
|
86
|
+
// primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@480c1083,
|
|
87
87
|
// doc = Doc(blocks = IndexedSeq(), metadata = Map()),
|
|
88
88
|
// modifiers = List(),
|
|
89
89
|
// storedDefaultValue = None,
|
|
@@ -97,7 +97,7 @@ dynamic
|
|
|
97
97
|
// value = Primitive(
|
|
98
98
|
// primitiveType = Int(None),
|
|
99
99
|
// typeId = Int,
|
|
100
|
-
// primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@
|
|
100
|
+
// primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@480c1083,
|
|
101
101
|
// doc = Doc(blocks = IndexedSeq(), metadata = Map()),
|
|
102
102
|
// modifiers = List(),
|
|
103
103
|
// storedDefaultValue = None,
|
|
@@ -115,7 +115,7 @@ dynamic
|
|
|
115
115
|
// value = Primitive(
|
|
116
116
|
// primitiveType = String(None),
|
|
117
117
|
// typeId = String,
|
|
118
|
-
// primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@
|
|
118
|
+
// primitiveBinding = zio.blocks.schema.binding.NoBinding$$anon$1@480c1083,
|
|
119
119
|
// doc = Doc(blocks = IndexedSeq(), metadata = Map()),
|
|
120
120
|
// modifiers = List(),
|
|
121
121
|
// storedDefaultValue = None,
|
|
@@ -232,7 +232,7 @@ dynSchema.check(valid)
|
|
|
232
232
|
dynSchema.check(missing)
|
|
233
233
|
// res8: Option[SchemaError] = Some(
|
|
234
234
|
// SchemaError(
|
|
235
|
-
// List(MissingField(source = DynamicOptic(
|
|
235
|
+
// List(MissingField(source = DynamicOptic(ArraySeq()), fieldName = "y"))
|
|
236
236
|
// )
|
|
237
237
|
// )
|
|
238
238
|
dynSchema.check(wrongType)
|
|
@@ -240,7 +240,7 @@ dynSchema.check(wrongType)
|
|
|
240
240
|
// SchemaError(
|
|
241
241
|
// List(
|
|
242
242
|
// ExpectationMismatch(
|
|
243
|
-
// source = DynamicOptic(
|
|
243
|
+
// source = DynamicOptic(ArraySeq(Field("y"))),
|
|
244
244
|
// expectation = "Expected Int, got String"
|
|
245
245
|
// )
|
|
246
246
|
// )
|
|
@@ -339,7 +339,7 @@ rebound.fromDynamicValue(encoded)
|
|
|
339
339
|
If `DynamicSchema#rebind` cannot find a binding for any type in the unbound schema tree, it throws a `RebindException` at runtime. Ensure the resolver covers every concrete type — records, variants, wrappers, primitives, and standard collections — that appears in the schema. `BindingResolver.defaults` covers all standard primitives, `java.time` types, `List`, `Map`, `Option`, and other standard collections.
|
|
340
340
|
:::
|
|
341
341
|
|
|
342
|
-
See [BindingResolver](
|
|
342
|
+
See [BindingResolver](binding-resolver.md) for the full resolver API including `BindingResolver.reflection` for automatic binding via reflection.
|
|
343
343
|
|
|
344
344
|
## Structural Navigation
|
|
345
345
|
|
|
@@ -546,7 +546,7 @@ gatewaySchema.fromDynamicValue(incoming)
|
|
|
546
546
|
|
|
547
547
|
### With `BindingResolver`
|
|
548
548
|
|
|
549
|
-
The primary consumer of `DynamicSchema` in a type-safe context is `DynamicSchema#rebind`, which requires a `BindingResolver` to reattach runtime bindings. See [BindingResolver](
|
|
549
|
+
The primary consumer of `DynamicSchema` in a type-safe context is `DynamicSchema#rebind`, which requires a `BindingResolver` to reattach runtime bindings. See [BindingResolver](binding-resolver.md) for the complete rebinding API, including `BindingResolver.reflection` for automatic binding discovery.
|
|
550
550
|
|
|
551
551
|
### With `DynamicOptic`
|
|
552
552
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: format
|
|
3
|
+
title: "Format Type"
|
|
4
|
+
sidebar_label: "Format"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
A `Format` is an abstraction that bundles together everything needed to serialize and deserialize data in a specific format (JSON, Avro, MessagePack, etc.). It unifies metadata related to serialization formats, such as MIME type and codec deriver, in a single place.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
The `Format` trait defines the structure for any serialization format. Each format specifies the types for decoding input, encoding output, the codec typeclass, MIME type, and the deriver used to generate codecs from schemas:
|
|
12
|
+
|
|
13
|
+
```scala
|
|
14
|
+
import zio.blocks.schema.codec.Codec
|
|
15
|
+
import zio.blocks.schema.derive.Deriver
|
|
16
|
+
|
|
17
|
+
trait Format {
|
|
18
|
+
type DecodeInput
|
|
19
|
+
type EncodeOutput
|
|
20
|
+
type TypeClass[A] <: Codec[DecodeInput, EncodeOutput, A]
|
|
21
|
+
def mimeType: String
|
|
22
|
+
def deriver: Deriver[TypeClass]
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This design 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.
|
|
27
|
+
|
|
28
|
+
## Using a Format
|
|
29
|
+
|
|
30
|
+
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 to obtain a codec that can encode and decode values of type `A` according to that format's rules:
|
|
31
|
+
|
|
32
|
+
```scala
|
|
33
|
+
import zio.blocks.schema._
|
|
34
|
+
import zio.blocks.schema.toon._
|
|
35
|
+
|
|
36
|
+
case class Person(name: String, age: Int)
|
|
37
|
+
|
|
38
|
+
object Person {
|
|
39
|
+
implicit val schema: Schema[Person] = Schema.derived
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
val codec = Schema[Person].derive(ToonFormat)
|
|
43
|
+
val bytes: Array[Byte] = codec.encode(Person("Alice", 30))
|
|
44
|
+
val decoded: Either[SchemaError, Person] = codec.decode(bytes)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Format Categories
|
|
48
|
+
|
|
49
|
+
Formats are categorized into `BinaryFormat` and `TextFormat`, which specify the types of input and output for encoding and decoding:
|
|
50
|
+
|
|
51
|
+
```scala
|
|
52
|
+
sealed trait Format
|
|
53
|
+
abstract class BinaryFormat[A] extends Format { }
|
|
54
|
+
abstract class TextFormat[A] extends Format { }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**BinaryFormat** — Encodes and decodes data as bytes. Used for compact, efficient serialization (e.g., Avro, Thrift, MessagePack).
|
|
58
|
+
|
|
59
|
+
**TextFormat** — Encodes and decodes data as text strings. Used for human-readable formats (e.g., JSON, YAML, TOON).
|
|
60
|
+
|
|
61
|
+
### Example: JsonFormat
|
|
62
|
+
|
|
63
|
+
The `JsonFormat` is a `BinaryFormat` that represents JSON serialization, where both the input for decoding and output for encoding are `ByteBuffer`, the MIME type is `application/json`, and the deriver for generating codecs from schemas is `JsonCodecDeriver`:
|
|
64
|
+
|
|
65
|
+
```scala
|
|
66
|
+
import zio.blocks.schema.json._
|
|
67
|
+
|
|
68
|
+
object MyJsonFormat extends zio.blocks.schema.codec.BinaryFormat("application/json", JsonCodecDeriver)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Defining a Custom Format
|
|
72
|
+
|
|
73
|
+
To add a new serialization format, define a `BinaryFormat` (or `TextFormat`) singleton with a custom `Deriver`:
|
|
74
|
+
|
|
75
|
+
```scala
|
|
76
|
+
import zio.blocks.schema.codec.BinaryCodec
|
|
77
|
+
|
|
78
|
+
// 1. Define your codec base class
|
|
79
|
+
abstract class MyCodec[A] extends BinaryCodec[A]
|
|
80
|
+
|
|
81
|
+
// 2. Implement a Deriver[MyCodec] (see Type-class Derivation docs)
|
|
82
|
+
// val myDeriver: Deriver[MyCodec] = ...
|
|
83
|
+
|
|
84
|
+
// 3. Create the format singleton
|
|
85
|
+
// object MyFormat extends BinaryFormat[MyCodec]("application/x-myformat", myDeriver)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For details on implementing a `Deriver`, see [Type-class Derivation](./type-class-derivation.md).
|
|
89
|
+
|
|
90
|
+
## Available Formats
|
|
91
|
+
|
|
92
|
+
ZIO Blocks provides multiple built-in formats. See the [Built-in Formats and Codecs](./built-in-codecs/index.md) section for a complete list of supported serialization formats and their respective codec modules.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: index
|
|
3
|
+
title: "ZIO Blocks Schema"
|
|
4
|
+
sidebar_label: "Schema"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Introduction
|
|
8
|
+
|
|
9
|
+
ZIO Blocks Schema is the core type system and serialization framework that provides reified structural metadata for Scala data types. It enables type-safe schema definition, validation, optics-based data access, multi-format serialization, and runtime introspection — all derived from a single `Schema` definition.
|
|
10
|
+
|
|
11
|
+
**Core Type System:**
|
|
12
|
+
- [`Schema`](./schema.md) — Primary data type containing reified structure of a Scala data type
|
|
13
|
+
- [`Reflect`](./reflect.md) — Foundational data structure containing reified structural information
|
|
14
|
+
- [`Binding`](./binding.md) — Operational machinery for constructing and deconstructing values
|
|
15
|
+
- [`Registers`](./registers.md) — Register-based design for zero-allocation construction and deconstruction
|
|
16
|
+
- [`Structural Types`](./structural-types.md) — Duck typing with ZIO Blocks schemas
|
|
17
|
+
|
|
18
|
+
**Dynamic & Runtime Data:**
|
|
19
|
+
- [`DynamicValue`](./dynamic-value.md) — Schema-less, dynamically-typed representation of any structured value
|
|
20
|
+
- [`DynamicSchema`](./dynamic-schema.md) — Type-erased schema container for serialization and transport
|
|
21
|
+
- [`Lazy`](./lazy.md) — Deferred computation with monadic abstraction, memoization, and stack-safe evaluation
|
|
22
|
+
|
|
23
|
+
**Navigation & Transformation:**
|
|
24
|
+
- [`Optics`](./optics.md) — Reflective optics for type-safe, composable access to nested data structures
|
|
25
|
+
- [`DynamicOptic`](./dynamic-optic.md) — Runtime path through nested data structures
|
|
26
|
+
- [`Path Interpolator`](./path-interpolator.md) — Compile-time string interpolator `p"..."` for constructing `DynamicOptic` instances
|
|
27
|
+
- [`SchemaExpr`](./schema-expr.md) — Schema-aware expressions for evaluation and query language translation
|
|
28
|
+
- [`Patch`](./patch.md) — Type-safe, serializable transformations of data structures
|
|
29
|
+
- [`Modifier`](./modifier.md) — Mechanism to attach metadata and configuration to schema elements
|
|
30
|
+
|
|
31
|
+
**Serialization:**
|
|
32
|
+
- [`Codec`](./codec.md) — Base abstraction for encoding and decoding values between formats
|
|
33
|
+
- [`Format`](./format.md) — Unified abstraction bundling serialization and deserialization for a specific format
|
|
34
|
+
- [`Type Class Derivation`](./type-class-derivation.md) — Automatic generation of type class instances from schemas
|
|
35
|
+
- [`Syntax`](./syntax.md) — Extension methods for fluent JSON encoding/decoding and patching
|
|
36
|
+
|
|
37
|
+
**Formats:**
|
|
38
|
+
- [`JSON Codec`](./built-in-codecs/json/) — Complete JSON support: ADT for JSON values, fluent navigation, encoding/decoding, diffs, patches, and JSON Schema 2020-12 validation
|
|
39
|
+
- [`Xml`](./built-in-codecs/xml.md) — Type-safe, immutable representation of XML document structures
|
|
40
|
+
|
|
41
|
+
**Validation & Errors:**
|
|
42
|
+
- [`Validation`](./validation.md) — Declarative constraints on primitive values
|
|
43
|
+
- [`SchemaError`](./schema-error.md) — Structured error type for schema operations
|
|
44
|
+
- [`Allows`](./allows.md) — Compile-time capability token proving a type satisfies a structural grammar
|
|
45
|
+
|
|
46
|
+
## Overview
|
|
47
|
+
|
|
48
|
+
The ZIO Blocks Schema module revolves around the `Schema` and `Reflect` types, which capture the complete structural description of Scala data types at runtime. From a single schema definition, you get automatic derivation of codecs (`Codec`, `Formats`), type-safe data access (`Optics`, `DynamicOptic`), structural validation (`Validation`, `SchemaError`), patching (`Patch`, `JsonPatch`), and serialization to multiple formats (`Json`, `Xml`, `JSON Schema`).
|
|
49
|
+
|
|
50
|
+
The type system is powered by a register-based architecture (`Registers`) that eliminates boxing overhead, and supports both compile-time (`Allows`) and runtime (`DynamicValue`, `DynamicSchema`) type manipulation. The `Deriver` system (`Type Class Derivation`) enables automatic generation of any type class instance from schema metadata.
|