@zio.dev/zio-blocks 0.0.33 → 0.0.55

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 (215) hide show
  1. package/adr/2026-07-18-data-migration.md +123 -0
  2. package/guides/async-getting-started.md +687 -0
  3. package/guides/compile-time-resource-safety-with-scope.md +21 -16
  4. package/guides/getting-started-with-mux.md +1395 -0
  5. package/guides/query-dsl-extending.md +161 -102
  6. package/guides/query-dsl-fluent-builder.md +217 -157
  7. package/guides/query-dsl-reified-optics.md +12 -10
  8. package/guides/query-dsl-sql.md +640 -165
  9. package/guides/sql-checked-interpolation.md +173 -0
  10. package/guides/sql-transactions.md +286 -0
  11. package/guides/telemetry-guide.md +1130 -0
  12. package/guides/zio-schema-migration.md +29 -22
  13. package/index.md +248 -389
  14. package/package.json +1 -1
  15. package/plans/config-follow-up-prs.md +188 -0
  16. package/plans/config-pr-assessment-roadmap.md +310 -0
  17. package/reference/MuxDataFlow.jsx +250 -0
  18. package/reference/async.md +1499 -0
  19. package/reference/chunk.md +3533 -308
  20. package/reference/codegen/case-class.md +436 -0
  21. package/reference/codegen/emitter-config.md +383 -0
  22. package/reference/codegen/examples.md +664 -0
  23. package/reference/codegen/field.md +316 -0
  24. package/reference/codegen/index.md +317 -0
  25. package/reference/codegen/scala-emitter.md +392 -0
  26. package/reference/codegen/scala-file.md +276 -0
  27. package/reference/codegen/sealed-trait.md +408 -0
  28. package/reference/codegen/type-definition.md +340 -0
  29. package/reference/codegen/type-ref.md +201 -0
  30. package/reference/combinators.md +347 -117
  31. package/reference/config/config-decoder.md +460 -0
  32. package/reference/config/config-source.md +489 -0
  33. package/reference/config/errors.md +278 -0
  34. package/reference/config/flags.md +369 -0
  35. package/reference/config/formats.md +314 -0
  36. package/reference/config/index.md +304 -0
  37. package/reference/config/rollout.md +336 -0
  38. package/reference/context.md +9 -52
  39. package/reference/data-migration.md +269 -0
  40. package/reference/datastar/attributes.md +302 -0
  41. package/reference/datastar/events.md +234 -0
  42. package/reference/datastar/index.md +256 -0
  43. package/reference/datastar/signals.md +230 -0
  44. package/reference/datastar/sse.md +295 -0
  45. package/reference/datastar.md +346 -0
  46. package/reference/docs.md +1461 -345
  47. package/reference/endpoint/auth-type.md +146 -0
  48. package/reference/endpoint/bulk-creation.md +96 -0
  49. package/reference/endpoint/endpoint.md +297 -0
  50. package/reference/endpoint/http-codec.md +249 -0
  51. package/reference/endpoint/index.md +745 -0
  52. package/reference/endpoint/path-codec.md +225 -0
  53. package/reference/endpoint/route-pattern.md +194 -0
  54. package/reference/endpoint/route-tree.md +111 -0
  55. package/reference/endpoint/segment-codec.md +199 -0
  56. package/reference/html.md +1424 -0
  57. package/reference/htmx/attribute-values.md +359 -0
  58. package/reference/htmx/hx-encoding.md +111 -0
  59. package/reference/htmx/hx-params.md +204 -0
  60. package/reference/htmx/hx-swap.md +276 -0
  61. package/reference/htmx/hx-sync.md +251 -0
  62. package/reference/htmx/hx-target.md +314 -0
  63. package/reference/htmx/hx-trigger.md +457 -0
  64. package/reference/htmx/hx-url-update.md +239 -0
  65. package/reference/htmx/index.md +807 -0
  66. package/reference/htmx/response-headers.md +240 -0
  67. package/reference/http-model/headers.md +735 -0
  68. package/reference/http-model/index.md +49 -0
  69. package/reference/http-model/model.md +1517 -0
  70. package/reference/http-model/schema-codecs.md +522 -0
  71. package/reference/http-model/schema.md +750 -0
  72. package/reference/http-model/server-sent-event.md +341 -0
  73. package/reference/jwt.md +195 -0
  74. package/reference/maybe.md +943 -0
  75. package/reference/media-type.md +2 -2
  76. package/reference/mux.md +254 -0
  77. package/reference/mux.mdx +828 -0
  78. package/reference/openapi.md +1351 -0
  79. package/reference/projection.md +654 -0
  80. package/reference/resource-management/defer-handle.md +1 -1
  81. package/reference/resource-management/resource.md +31 -98
  82. package/reference/resource-management/scope.md +28 -220
  83. package/reference/resource-management/wire.md +5 -55
  84. package/reference/ringbuffer/MpmcDiagram.jsx +717 -0
  85. package/reference/ringbuffer/MpscDiagram.jsx +618 -0
  86. package/reference/ringbuffer/SpmcDiagram.jsx +680 -0
  87. package/reference/ringbuffer/SpscDiagram.jsx +677 -0
  88. package/reference/ringbuffer/advanced.mdx +109 -0
  89. package/reference/ringbuffer/index.mdx +145 -0
  90. package/reference/ringbuffer/mpmc.mdx +185 -0
  91. package/reference/ringbuffer/mpsc.mdx +164 -0
  92. package/reference/ringbuffer/spmc.mdx +108 -0
  93. package/reference/ringbuffer/spsc.mdx +416 -0
  94. package/reference/{allows.md → schema/allows.md} +4 -100
  95. package/reference/{binding-resolver.md → schema/binding-resolver.md} +1 -1
  96. package/reference/{binding.md → schema/binding.md} +3 -4
  97. package/reference/schema/built-in-codecs/avro.md +451 -0
  98. package/reference/schema/built-in-codecs/bson.md +510 -0
  99. package/reference/schema/built-in-codecs/csv.md +564 -0
  100. package/reference/schema/built-in-codecs/index.md +77 -0
  101. package/reference/schema/built-in-codecs/json/index.md +295 -0
  102. package/reference/schema/built-in-codecs/json/json-config.md +217 -0
  103. package/reference/{json-patch.md → schema/built-in-codecs/json/json-patch.md} +5 -5
  104. package/reference/{json-schema.md → schema/built-in-codecs/json/json-schema.md} +14 -47
  105. package/reference/schema/built-in-codecs/json/json-selection.md +322 -0
  106. package/reference/{json.md → schema/built-in-codecs/json/json.md} +32 -64
  107. package/reference/schema/built-in-codecs/messagepack.md +508 -0
  108. package/reference/schema/built-in-codecs/thrift.md +433 -0
  109. package/reference/schema/built-in-codecs/toon.md +1078 -0
  110. package/reference/{xml.md → schema/built-in-codecs/xml.md} +13 -9
  111. package/reference/schema/built-in-codecs/yaml.md +552 -0
  112. package/reference/{codec.md → schema/codec.md} +11 -11
  113. package/reference/{dynamic-optic.md → schema/dynamic-optic.md} +196 -5
  114. package/reference/{dynamic-schema.md → schema/dynamic-schema.md} +8 -8
  115. package/reference/schema/format.md +92 -0
  116. package/reference/schema/index.md +52 -0
  117. package/reference/schema/migration.md +297 -0
  118. package/reference/{modifier.md → schema/modifier.md} +58 -7
  119. package/reference/{optics.md → schema/optics.md} +2 -2
  120. package/reference/{patch.md → schema/patch.md} +1 -1
  121. package/{path-interpolator.md → reference/schema/path-interpolator.md} +167 -72
  122. package/reference/schema/reflect-transformer.md +140 -0
  123. package/reference/{schema-evolution → schema/schema-evolution}/as.md +8 -8
  124. package/reference/{schema-evolution → schema/schema-evolution}/index.md +2 -2
  125. package/reference/{schema-evolution → schema/schema-evolution}/into.md +8 -8
  126. package/reference/{schema-expr.md → schema/schema-expr.md} +110 -175
  127. package/reference/schema/schema-search.md +263 -0
  128. package/reference/{schema.md → schema/schema.md} +22 -2
  129. package/reference/{structural-types.md → schema/structural-types.md} +1 -1
  130. package/reference/{type-class-derivation.md → schema/type-class-derivation.md} +63 -1
  131. package/reference/smithy.md +1032 -0
  132. package/reference/sql/db-codec-deriver.md +71 -0
  133. package/reference/sql/db-codec.md +687 -0
  134. package/reference/sql/db-con.md +271 -0
  135. package/reference/sql/db-connection.md +153 -0
  136. package/reference/sql/db-param-writer.md +77 -0
  137. package/reference/sql/db-param.md +66 -0
  138. package/reference/sql/db-result-reader.md +148 -0
  139. package/reference/sql/db-tx.md +114 -0
  140. package/reference/sql/db-value.md +41 -0
  141. package/reference/sql/ddl.md +85 -0
  142. package/reference/sql/frag.md +288 -0
  143. package/reference/sql/index.md +341 -0
  144. package/reference/sql/repo.md +600 -0
  145. package/reference/sql/sql-dialect.md +73 -0
  146. package/reference/sql/sql-logger.md +62 -0
  147. package/reference/sql/sql-name-mapper.md +70 -0
  148. package/reference/sql/table-metadata.md +134 -0
  149. package/reference/sql/table.md +448 -0
  150. package/reference/sql/transactor-zio.md +399 -0
  151. package/reference/sql/transactor.md +363 -0
  152. package/reference/sql-zio.md +112 -0
  153. package/reference/streams/core/index.md +32 -0
  154. package/reference/streams/core/pipeline.md +854 -0
  155. package/reference/streams/core/sink.md +1404 -0
  156. package/reference/streams/core/stream.md +3236 -0
  157. package/reference/streams/execution-and-compatibility/async-execution.md +822 -0
  158. package/reference/streams/execution-and-compatibility/index.md +35 -0
  159. package/reference/streams/execution-and-compatibility/platform-differences.md +297 -0
  160. package/reference/streams/execution-and-compatibility/scala-2-compatibility.md +88 -0
  161. package/reference/streams/execution-and-compatibility/zero-boxing.md +393 -0
  162. package/reference/streams/index.md +726 -0
  163. package/reference/streams/primitives/index.md +30 -0
  164. package/reference/streams/primitives/reader.md +1992 -0
  165. package/reference/streams/primitives/writer.md +1201 -0
  166. package/reference/telemetry/common/any-value.md +90 -0
  167. package/reference/telemetry/common/attribute-key.md +87 -0
  168. package/reference/telemetry/common/attributes.md +118 -0
  169. package/reference/telemetry/common/index.md +39 -0
  170. package/reference/telemetry/common/instrumentation-scope.md +24 -0
  171. package/reference/telemetry/common/resource.md +34 -0
  172. package/reference/telemetry/index.md +311 -0
  173. package/reference/telemetry/logging/index.md +197 -0
  174. package/reference/telemetry/logging/log-enrichment.md +72 -0
  175. package/reference/telemetry/logging/log-formatter.md +100 -0
  176. package/reference/telemetry/logging/log-record-processor.md +56 -0
  177. package/reference/telemetry/logging/log-record.md +44 -0
  178. package/reference/telemetry/logging/log-writer.md +64 -0
  179. package/reference/telemetry/logging/logger-provider.md +142 -0
  180. package/reference/telemetry/logging/logger.md +83 -0
  181. package/reference/telemetry/logging/severity.md +62 -0
  182. package/reference/telemetry/metrics/index.md +150 -0
  183. package/reference/telemetry/metrics/instruments.md +183 -0
  184. package/reference/telemetry/metrics/labeled-instruments.md +74 -0
  185. package/reference/telemetry/metrics/meter-provider.md +76 -0
  186. package/reference/telemetry/metrics/meter.md +98 -0
  187. package/reference/telemetry/metrics/metric-data.md +57 -0
  188. package/reference/telemetry/otel/custom-exporter.md +216 -0
  189. package/reference/telemetry/otel/index.md +212 -0
  190. package/reference/telemetry/tracing/index.md +155 -0
  191. package/reference/telemetry/tracing/sampler.md +89 -0
  192. package/reference/telemetry/tracing/span-builder.md +57 -0
  193. package/reference/telemetry/tracing/span-context.md +39 -0
  194. package/reference/telemetry/tracing/span-data.md +32 -0
  195. package/reference/telemetry/tracing/span-kind.md +55 -0
  196. package/reference/telemetry/tracing/span-processor.md +53 -0
  197. package/reference/telemetry/tracing/span-status.md +47 -0
  198. package/reference/telemetry/tracing/span.md +117 -0
  199. package/reference/telemetry/tracing/tracer-provider.md +91 -0
  200. package/reference/telemetry/tracing/tracer.md +52 -0
  201. package/reference/typeid.md +5 -83
  202. package/sidebars.js +376 -43
  203. package/undocumented-report.md +528 -270
  204. package/reference/formats.md +0 -694
  205. package/reference/http-model.md +0 -1716
  206. package/reference/streams.md +0 -989
  207. package/ringbuffer.md +0 -249
  208. /package/reference/{json-differ.md → schema/built-in-codecs/json/json-differ.md} +0 -0
  209. /package/reference/{dynamic-value.md → schema/dynamic-value.md} +0 -0
  210. /package/reference/{lazy.md → schema/lazy.md} +0 -0
  211. /package/reference/{reflect.md → schema/reflect.md} +0 -0
  212. /package/reference/{registers.md → schema/registers.md} +0 -0
  213. /package/reference/{schema-error.md → schema/schema-error.md} +0 -0
  214. /package/reference/{syntax.md → schema/syntax.md} +0 -0
  215. /package/reference/{validation.md → schema/validation.md} +0 -0
@@ -3,13 +3,20 @@ id: path-interpolator
3
3
  title: "Path Interpolator"
4
4
  ---
5
5
 
6
+ :::note
7
+ To use the path interpolator `p"..."`, you must import the schema package: `import zio.blocks.schema._`
8
+ :::
9
+
6
10
  The path interpolator `p"..."` is a compile-time string interpolator for constructing `DynamicOptic` instances in ZIO Blocks. It provides a clean, concise syntax for building optic paths that navigate through complex data structures, with all parsing and validation happening at compile time for zero runtime overhead.
7
11
 
8
12
  **Why use the path interpolator?**
9
13
 
10
14
  Instead of manually constructing optics like this:
11
15
 
16
+
12
17
  ```scala
18
+ import zio.blocks.schema._
19
+
13
20
  DynamicOptic(Vector(
14
21
  DynamicOptic.Node.Field("users"),
15
22
  DynamicOptic.Node.Elements,
@@ -20,6 +27,8 @@ DynamicOptic(Vector(
20
27
  You can write:
21
28
 
22
29
  ```scala
30
+ import zio.blocks.schema._
31
+
23
32
  p".users[*].email"
24
33
  ```
25
34
 
@@ -46,9 +55,11 @@ val path = p".users[0].name"
46
55
 
47
56
  ## Syntax Reference
48
57
 
58
+ This section documents the complete path syntax with examples for each component type.
59
+
49
60
  ### Field Access
50
61
 
51
- Access fields in records using dot notation. The leading dot is optional.
62
+ Access fields in records using dot notation. The leading dot is optional:
52
63
 
53
64
  ```scala
54
65
  // With leading dot
@@ -64,7 +75,7 @@ p".user.address.street"
64
75
  // Equivalent to: Field("user") → Field("address") → Field("street")
65
76
  ```
66
77
 
67
- **Special cases:**
78
+ Field names can also include special characters and keywords:
68
79
 
69
80
  ```scala
70
81
  p"._private" // Fields starting with underscore
@@ -77,7 +88,7 @@ p".true" // Keywords as field names (true, false, null)
77
88
 
78
89
  Access sequence elements by index, multiple indices, or ranges.
79
90
 
80
- **Single index:**
91
+ To access a single element by index:
81
92
 
82
93
  ```scala
83
94
  p"[0]" // AtIndex(0)
@@ -85,7 +96,7 @@ p"[42]" // AtIndex(42)
85
96
  p"[2147483647]" // AtIndex(Int.MaxValue)
86
97
  ```
87
98
 
88
- **Multiple indices:**
99
+ To access multiple elements at specific indices:
89
100
 
90
101
  ```scala
91
102
  p"[0,1,2]" // AtIndices(Seq(0, 1, 2))
@@ -93,7 +104,7 @@ p"[0, 2, 5]" // AtIndices(Seq(0, 2, 5)) - spaces allowed
93
104
  p"[5,2,8,1]" // Order preserved
94
105
  ```
95
106
 
96
- **Ranges:**
107
+ To select a range of consecutive elements:
97
108
 
98
109
  ```scala
99
110
  p"[0:5]" // AtIndices(Seq(0, 1, 2, 3, 4))
@@ -105,14 +116,14 @@ p"[10:5]" // AtIndices(Seq.empty) - inverted range
105
116
 
106
117
  ### Element Selectors
107
118
 
108
- Select all elements in a sequence using wildcard syntax.
119
+ Select all elements in a sequence using wildcard syntax:
109
120
 
110
121
  ```scala
111
122
  p"[*]" // Elements - all elements
112
123
  p"[:*]" // Elements - alternative syntax
113
124
  ```
114
125
 
115
- **Chained selectors:**
126
+ To navigate nested sequences:
116
127
 
117
128
  ```scala
118
129
  p"[*][*]" // Nested sequences: all elements of all elements
@@ -123,7 +134,7 @@ p"[*][0]" // First element of each sequence
123
134
 
124
135
  Access map values by key, where keys can be strings, integers, booleans, or characters.
125
136
 
126
- **String keys:**
137
+ To use string keys:
127
138
 
128
139
  ```scala
129
140
  p"""{"host"}""" // AtMapKey(String("host"))
@@ -133,7 +144,7 @@ p"""{"🎉"}""" // Emoji keys
133
144
  p"""{""}""" // Empty string key
134
145
  ```
135
146
 
136
- **Integer keys:**
147
+ To use integer keys:
137
148
 
138
149
  ```scala
139
150
  p"{42}" // AtMapKey(Int(42))
@@ -143,14 +154,14 @@ p"{2147483647}" // AtMapKey(Int.MaxValue)
143
154
  p"{-2147483648}" // AtMapKey(Int.MinValue)
144
155
  ```
145
156
 
146
- **Boolean keys:**
157
+ To use boolean keys:
147
158
 
148
159
  ```scala
149
160
  p"{true}" // AtMapKey(Boolean(true))
150
161
  p"{false}" // AtMapKey(Boolean(false))
151
162
  ```
152
163
 
153
- **Char keys:**
164
+ To use character keys:
154
165
 
155
166
  ```scala
156
167
  p"{'a'}" // AtMapKey(Char('a'))
@@ -158,7 +169,7 @@ p"{' '}" // AtMapKey(Char(' '))
158
169
  p"{'9'}" // AtMapKey(Char('9'))
159
170
  ```
160
171
 
161
- **Multiple keys:**
172
+ To use multiple keys of the same or mixed types:
162
173
 
163
174
  ```scala
164
175
  p"""{"foo", "bar", "baz"}""" // AtMapKeys(Seq(...))
@@ -172,7 +183,7 @@ p"""{"s", 'c', 42, true}""" // All supported types
172
183
 
173
184
  ### Map Selectors
174
185
 
175
- Select all keys or all values in a map.
186
+ Select all keys or all values in a map:
176
187
 
177
188
  ```scala
178
189
  p"{*}" // MapValues - all values
@@ -180,7 +191,7 @@ p"{:*}" // MapValues - alternative syntax
180
191
  p"{*:}" // MapKeys - all keys
181
192
  ```
182
193
 
183
- **Examples:**
194
+ To apply map selectors to nested maps:
184
195
 
185
196
  ```scala
186
197
  p"{*}{*}" // Nested maps: all values of all values
@@ -189,7 +200,7 @@ p"{*:}{*:}" // All keys of all keys
189
200
 
190
201
  ### Variant Case Access
191
202
 
192
- Navigate into a specific variant case using angle brackets.
203
+ Navigate into a specific variant case using angle brackets:
193
204
 
194
205
  ```scala
195
206
  p"<Left>" // Case("Left")
@@ -198,7 +209,7 @@ p"<Some>" // Case("Some")
198
209
  p"<None>" // Case("None")
199
210
  ```
200
211
 
201
- **Special cases:**
212
+ Variant case names can include special characters and keywords:
202
213
 
203
214
  ```scala
204
215
  p"<_Empty>" // Cases starting with underscore
@@ -206,7 +217,7 @@ p"<Case1>" // Cases with digits
206
217
  p"<café>" // Unicode case names
207
218
  ```
208
219
 
209
- **Chained cases:**
220
+ To navigate nested variant cases:
210
221
 
211
222
  ```scala
212
223
  p"<A><B><C>" // Nested variants
@@ -216,7 +227,7 @@ p"<A><B><C>" // Nested variants
216
227
 
217
228
  Search for values matching a schema pattern anywhere in a data structure using the `#` prefix.
218
229
 
219
- **Nominal types:**
230
+ To search for nominal types by name:
220
231
 
221
232
  ```scala
222
233
  p"#Person" // Find all values of type Person
@@ -224,7 +235,7 @@ p"#User" // Find all values of type User
224
235
  p"#Address" // Find all values of type Address
225
236
  ```
226
237
 
227
- **Primitive types:**
238
+ To search for primitive types:
228
239
 
229
240
  ```scala
230
241
  p"#string" // Find all string values
@@ -233,7 +244,7 @@ p"#boolean" // Find all boolean values
233
244
  p"#uuid" // Find all UUID values
234
245
  ```
235
246
 
236
- **Structural records:**
247
+ To search for records with specific field structures:
237
248
 
238
249
  ```scala
239
250
  p"#record { name: string }" // Find records with a string 'name' field
@@ -241,13 +252,13 @@ p"#record { name: string, age: int }" // Find records with both fields
241
252
  p"#record { items: list(Person) }" // Nested schema
242
253
  ```
243
254
 
244
- **Structural variants:**
255
+ To search for variants with specific case structures:
245
256
 
246
257
  ```scala
247
258
  p"#variant { Left: int, Right: string }" // Find Either-like variants
248
259
  ```
249
260
 
250
- **Collections:**
261
+ To search for collection types:
251
262
 
252
263
  ```scala
253
264
  p"#list(string)" // Find lists of strings
@@ -256,13 +267,15 @@ p"#map(string, int)" // Find maps from string to int
256
267
  p"#option(Person)" // Find optional Person values
257
268
  ```
258
269
 
259
- **Wildcard:**
270
+ `set(...)` and `vector(...)` work as synonyms for `list(...)` — all three parse to the same `SchemaRepr.Sequence` pattern, since the pattern only cares about the element type, not which collection it comes from.
271
+
272
+ To match any value regardless of type:
260
273
 
261
274
  ```scala
262
275
  p"#_" // Find any value (matches everything)
263
276
  ```
264
277
 
265
- **Combined paths with search:**
278
+ To combine path navigation with schema search:
266
279
 
267
280
  ```scala
268
281
  p".users#Person" // Search for Person in users field
@@ -284,7 +297,7 @@ String and character literals support standard escape sequences:
284
297
  | `\"` | `"` | Double quote |
285
298
  | `\\` | `\` | Backslash |
286
299
 
287
- **Examples:**
300
+ Here are some examples of escape sequences in use:
288
301
 
289
302
  ```scala
290
303
  p"""{"foo\nbar"}""" // String key with newline
@@ -300,6 +313,8 @@ Combine different path elements to navigate complex nested structures.
300
313
 
301
314
  ### Field → Sequence
302
315
 
316
+ Access sequence elements by index or range through a field:
317
+
303
318
  ```scala
304
319
  p".items[0]" // First item
305
320
  p".items[*]" // All items
@@ -309,6 +324,8 @@ p".items[0:5]" // Items 0 through 4
309
324
 
310
325
  ### Field → Map
311
326
 
327
+ Access map values by key through a field:
328
+
312
329
  ```scala
313
330
  p""".config{"host"}""" // Map lookup
314
331
  p".settings{42}" // Integer key
@@ -318,6 +335,8 @@ p".lookup{*:}" // All map keys
318
335
 
319
336
  ### Field → Variant
320
337
 
338
+ Navigate into variant cases through a field:
339
+
321
340
  ```scala
322
341
  p".result<Success>" // Variant case
323
342
  p".response<Ok>" // HTTP response variant
@@ -325,6 +344,8 @@ p".response<Ok>" // HTTP response variant
325
344
 
326
345
  ### Nested Structures
327
346
 
347
+ Combine different path elements to build complex navigation through nested data:
348
+
328
349
  ```scala
329
350
  // Record in sequence
330
351
  p".users[0].name"
@@ -345,6 +366,8 @@ p".response<Ok>.body"
345
366
 
346
367
  ### Deeply Nested Paths
347
368
 
369
+ Chain multiple path operators for deeply nested data structures:
370
+
348
371
  ```scala
349
372
  // Complex nested navigation
350
373
  p""".root.children[*].metadata{"tags"}[0]"""
@@ -359,35 +382,47 @@ p""".a[0]{"k"}<V>.b[*]{*}.c{*:}"""
359
382
 
360
383
  ## Root and Empty Paths
361
384
 
385
+ An empty path refers to the root of the data structure:
386
+
362
387
  ```scala
363
388
  p"" // Empty path = root
364
- // Equivalent to: DynamicOptic.root
365
- // Equivalent to: DynamicOptic(Vector.empty)
366
389
  ```
367
390
 
368
391
  ## Compile-Time Safety
369
392
 
370
393
  The path interpolator **rejects runtime interpolation** to prevent unsafe dynamic path construction.
371
394
 
372
- **❌ This will fail to compile:**
395
+ ### Examples of Safety Checks
396
+
397
+ Runtime interpolation will fail to compile:
373
398
 
374
399
  ```scala
400
+ import zio.blocks.schema._
401
+
375
402
  val fieldName = "email"
376
403
  val path = p".$fieldName"
377
404
  // Error: Path interpolator does not support runtime arguments.
378
- // Use only literal strings like p".field[0]"
405
+ // error:
406
+ // Path interpolator does not support runtime arguments. Use only literal strings like p".field[0]"
407
+ // val path = p".$fieldName"
408
+ // ^^^^^^^^^^^^^
379
409
  ```
380
410
 
381
- **❌ This will also fail:**
411
+ Array indices also cannot be interpolated at runtime:
382
412
 
383
413
  ```scala
414
+ import zio.blocks.schema._
415
+
384
416
  val idx = 5
385
417
  val path = p"[$idx]"
386
418
  // Error: Path interpolator does not support runtime arguments.
387
- // Use only literal strings like p".field[0]"
419
+ // error:
420
+ // Path interpolator does not support runtime arguments. Use only literal strings like p".field[0]"
421
+ // val path = p"[$idx]"
422
+ // ^^^^^^^^^
388
423
  ```
389
424
 
390
- **✅ Use only literal strings:**
425
+ Instead, use only literal strings at compile time:
391
426
 
392
427
  ```scala
393
428
  val path = p".users[0].email" // ✓ Works
@@ -395,31 +430,46 @@ val path = p".users[0].email" // ✓ Works
395
430
 
396
431
  ### Parse Error Examples
397
432
 
398
- Invalid syntax is caught at compile time:
433
+ Invalid syntax is caught at compile time. Here are examples of common errors:
399
434
 
400
435
  ```scala
436
+ import zio.blocks.schema._
437
+
401
438
  // Unterminated string
402
439
  p"""{"foo"""
403
- // Error: Unterminated string literal starting at position 1
440
+ // Error: Unterminated string literal
404
441
 
405
- // Invalid escape sequence
442
+ // Invalid escape sequence
406
443
  p"""{"foo\x"}"""
407
- // Error: Invalid escape sequence '\x' at position 6
444
+ // Error: Invalid escape sequence
408
445
 
409
446
  // Unexpected character
410
447
  p".field@"
411
- // Error: Unexpected character '@' at position 6
448
+ // Error: Unexpected character '@'
412
449
 
413
450
  // Invalid identifier
414
451
  p"."
415
- // Error: Invalid identifier at position 1
452
+ // Error: Invalid identifier
453
+ // error:
454
+ // Unterminated string literal starting at position 1
455
+ // error:
456
+ // Invalid escape sequence '\x' at position 6
457
+ // error:
458
+ // Unexpected character '@' at position 6. Expected field, index, map, or variant accessor
459
+ // error:
460
+ // Invalid identifier at position 1
461
+ // error:
462
+ // Conflicting definitions:
463
+ // val path: zio.blocks.schema.DynamicOptic in object MdocApp at line 14 and
464
+ // val path: zio.blocks.schema.DynamicOptic in object MdocApp at line 114
465
+ //
416
466
  ```
417
467
 
418
468
  ## Performance
419
469
 
420
470
  **Zero Runtime Overhead**
421
471
 
422
- All path parsing and validation occurs at **compile time**. The interpolator generates the exact same bytecode as manual `DynamicOptic` construction:
472
+ All path parsing and validation occurs at **compile time**. The interpolator generates the exact same bytecode as manual `DynamicOptic` construction. Here's the comparison:
423
473
 
424
474
  ```scala
425
475
  // These produce identical bytecode:
@@ -436,8 +486,12 @@ There is **no runtime parsing**, **no reflection**, and **no performance penalty
436
486
 
437
487
  ## Examples
438
488
 
489
+ This section shows practical examples of using the path interpolator with realistic data structures.
490
+
439
491
  ### Accessing Nested Fields
440
492
 
493
+ To access deeply nested fields in a data structure:
494
+
441
495
  ```scala
442
496
  import zio.blocks.schema._
443
497
 
@@ -447,14 +501,18 @@ case class Person(name: String, age: Int, address: Address)
447
501
  // Access nested street field
448
502
  val streetPath = p".address.street"
449
503
 
450
- // Use with DynamicValue
451
- val person = DynamicValue.fromPerson(...)
504
+ // Use with DynamicValue - example (requires actual DynamicValue instance)
505
+ val person: DynamicValue = ???
452
506
  val street = person.get(streetPath)
453
507
  ```
454
508
 
455
509
  ### Working with Collections
456
510
 
511
+ To work with sequences and access elements by index or range:
512
+
457
513
  ```scala
514
+ import zio.blocks.schema._
515
+
458
516
  case class User(id: Int, email: String, tags: Seq[String])
459
517
  case class Company(name: String, users: Seq[User])
460
518
 
@@ -470,7 +528,11 @@ val specificUsersPath = p".users[0,2,5]"
470
528
 
471
529
  ### Map Lookups
472
530
 
531
+ To work with map data structures and access values by key:
532
+
473
533
  ```scala
534
+ import zio.blocks.schema._
535
+
474
536
  case class Config(
475
537
  settings: Map[String, String],
476
538
  ports: Map[Int, String]
@@ -491,13 +553,21 @@ val allPortsPath = p"ports{*:}"
491
553
 
492
554
  ### Variant Case Handling
493
555
 
556
+ To navigate variant cases in your data structures:
557
+
494
558
  ```scala
559
+ import zio.blocks.schema._
560
+
495
561
  sealed trait Result[+A]
496
562
  case class Success[A](value: A) extends Result[A]
497
563
  case class Failure(error: String) extends Result[Nothing]
498
564
 
499
565
  case class Response(result: Result[User])
566
+ ```
567
+
568
+ Use paths to navigate into specific cases:
500
569
 
570
+ ```scala
501
571
  // Navigate into Success case
502
572
  val successValuePath = p".result<Success>.value"
503
573
 
@@ -507,7 +577,11 @@ val errorPath = p".result<Failure>.error"
507
577
 
508
578
  ### Real-World Example: API Response
509
579
 
580
+ To extract specific data from complex nested API response structures:
581
+
510
582
  ```scala
583
+ import zio.blocks.schema._
584
+
511
585
  case class Metadata(tags: Seq[String], version: Int)
512
586
  case class Item(id: String, data: String, metadata: Metadata)
513
587
  case class ApiResponse(
@@ -531,8 +605,12 @@ val apiKeyPath = p"""config{"api_key"}"""
531
605
 
532
606
  ## Before & After Comparison
533
607
 
608
+ This comparison shows how the path interpolator simplifies optic path construction compared to manual approaches.
609
+
534
610
  ### Manual Construction (Before)
535
611
 
612
+ Manual path construction requires verbose imports and careful construction:
613
+
536
614
  ```scala
537
615
  import zio.blocks.schema.DynamicOptic
538
616
  import zio.blocks.schema.DynamicOptic.Node
@@ -582,7 +660,7 @@ val path2 = p""".root.children[*].metadata{"tags"}[0]"""
582
660
  val path3 = p"""data{"foo", "bar", 42}"""
583
661
  ```
584
662
 
585
- **Benefits:**
663
+ The path interpolator provides significant benefits:
586
664
 
587
665
  - **90% less code** for typical paths
588
666
  - **Easier to read** and understand intent
@@ -592,9 +670,15 @@ val path3 = p"""data{"foo", "bar", 42}"""
592
670
 
593
671
  ## Practical Usage Patterns
594
672
 
673
+ These patterns demonstrate effective ways to use the path interpolator in real-world scenarios.
674
+
595
675
  ### Building Paths Dynamically (at Compile Time)
596
676
 
677
+ While runtime variables are not supported, you can compose literal paths at compile time:
678
+
597
679
  ```scala
680
+ import zio.blocks.schema._
681
+
598
682
  // You can't use runtime variables, but you can compose literal paths:
599
683
  val basePath = p".data.items"
600
684
  val emailPath = basePath(p"[*].email")
@@ -603,26 +687,31 @@ val emailPath = basePath(p"[*].email")
603
687
 
604
688
  ### Working with DynamicValue
605
689
 
690
+ To navigate and extract values from dynamic data:
691
+
606
692
  ```scala
607
693
  import zio.blocks.schema._
608
694
 
609
- val data: DynamicValue = ...
695
+ val data: DynamicValue = ???
610
696
 
611
697
  // Navigate and extract
612
698
  val value = data.get(p".users[0].email")
613
699
 
614
- // Update at path
615
- val updated = data.set(p".users[0].age", DynamicValue.fromInt(30))
700
+ // Update at path (using appropriate constructor)
701
+ val ageValue: DynamicValue = ???
702
+ val updated = data.set(p".users[0].age", ageValue)
616
703
  ```
617
704
 
618
705
  ### Integration with Schema Optics
619
706
 
707
+ To use path interpolators with schema-based optics:
708
+
620
709
  ```scala
621
710
  import zio.blocks.schema._
622
711
 
623
- case class User(name: String, email: String)
624
- object User extends CompanionOptics[User] {
625
- implicit val schema: Schema[User] = Schema.derived
712
+ case class UserRecord(name: String, email: String)
713
+ object UserRecord extends CompanionOptics[UserRecord] {
714
+ implicit val schema: Schema[UserRecord] = Schema.derived
626
715
 
627
716
  // Use path interpolator for complex lenses
628
717
  val email = $(_.email)
@@ -634,23 +723,22 @@ val dynamicPath = p".email"
634
723
 
635
724
  ## Tips and Best Practices
636
725
 
637
- 1. **Use the leading dot for clarity**: While optional, `p".field"` is more explicit than `p"field"`
726
+ 1. **Use the leading dot for clarity**: While optional, `p".field"` is more explicit than `p"field"`:
638
727
 
639
- 2. **Leverage compile-time validation**: Let the compiler catch typos and syntax errors early
640
-
641
- 3. **Compose paths when needed**: Break complex paths into reusable components
642
- ```scala
728
+ ```scala mdoc:compile-only
643
729
  val userPath = p".users[0]"
644
730
  val emailPath = userPath(p".email")
645
731
  ```
646
732
 
647
- 4. **Use raw strings for map keys**: Triple-quoted strings avoid escape hell
648
- ```scala
733
+ 4. **Use raw strings for map keys**: Triple-quoted strings avoid escape hell:
734
+
735
+ ```scala mdoc:compile-only
649
736
  p"""config{"api.key"}""" // Better than p"config{\"api.key\"}"
650
737
  ```
651
738
 
652
- 5. **Document complex paths**: Add comments explaining what nested paths navigate
653
- ```scala
739
+ 5. **Document complex paths**: Add comments explaining what nested paths navigate:
740
+
741
+ ```scala mdoc:compile-only
654
742
  // Get the first tag from each user's metadata
655
743
  val tagsPath = p".users[*].metadata.tags[0]"
656
744
  ```
@@ -670,29 +758,36 @@ These limitations ensure compile-time safety and zero runtime overhead.
670
758
 
671
759
  ```scala
672
760
  val optic = DynamicOptic.root.field("users").elements.field("email")
761
+ // optic: DynamicOptic = DynamicOptic(
762
+ // IndexedSeq(Field("users"), Elements, Field("email"))
763
+ // )
673
764
  println(optic) // Output: .users[*].email
765
+ // .users[*].email
674
766
 
675
767
  // The output can be copy-pasted into p"..."
676
768
  val same = p".users[*].email"
769
+ // same: DynamicOptic = DynamicOptic(
770
+ // Vector(Field("users"), Elements, Field("email"))
771
+ // )
677
772
  ```
678
773
 
679
774
  **Examples:**
680
775
 
681
- | DynamicOptic Construction | toString Output |
682
- |------------------------------------------------------|-------------------|
683
- | `DynamicOptic.root.field("name")` | `.name` |
684
- | `DynamicOptic.root.field("address").field("street")` | `.address.street` |
685
- | `DynamicOptic.root.caseOf("Some")` | `<Some>` |
686
- | `DynamicOptic.root.at(0)` | `[0]` |
687
- | `DynamicOptic.root.atIndices(0, 2, 5)` | `[0,2,5]` |
688
- | `DynamicOptic.elements` | `[*]` |
689
- | `DynamicOptic.root.atKey("host")` | `{"host"}` |
690
- | `DynamicOptic.root.atKey(80)` | `{80}` |
691
- | `DynamicOptic.mapValues` | `{*}` |
692
- | `DynamicOptic.mapKeys` | `{*:}` |
693
- | `DynamicOptic.wrapped` | `.~` |
694
- | `DynamicOptic.root.searchSchema(SchemaRepr.Nominal("Person"))` | `#Person` |
695
- | `DynamicOptic.root.searchSchema(SchemaRepr.Primitive("string"))` | `#string` |
776
+ | DynamicOptic Construction | Interpolator Syntax |
777
+ |------------------------------------------------------|---------------------|
778
+ | `DynamicOptic.root.field("name")` | `p".name"` |
779
+ | `DynamicOptic.root.field("address").field("street")` | `p".address.street"` |
780
+ | `DynamicOptic.root.caseOf("Some")` | `p"<Some>"` |
781
+ | `DynamicOptic.root.at(0)` | `p"[0]"` |
782
+ | `DynamicOptic.root.atIndices(0, 2, 5)` | `p"[0,2,5]"` |
783
+ | `DynamicOptic.elements` | `p"[*]"` |
784
+ | `DynamicOptic.root.atKey("host")` | `p"{"host"}"` |
785
+ | `DynamicOptic.root.atKey(80)` | `p"{80}"` |
786
+ | `DynamicOptic.mapValues` | `p"{*}"` |
787
+ | `DynamicOptic.mapKeys` | `p"{*:}"` |
788
+ | `DynamicOptic.wrapped` | `p".~"` |
789
+ | `DynamicOptic.root.searchSchema(SchemaRepr.Nominal("Person"))` | `p"#Person"` |
790
+ | `DynamicOptic.root.searchSchema(SchemaRepr.Primitive("string"))` | `p"#string"` |
696
791
 
697
792
  ## Summary
698
793