@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.
Files changed (150) hide show
  1. package/guides/compile-time-resource-safety-with-scope.md +16 -17
  2. package/guides/getting-started-with-mux.md +1507 -0
  3. package/guides/query-dsl-extending.md +161 -102
  4. package/guides/query-dsl-fluent-builder.md +217 -157
  5. package/guides/query-dsl-reified-optics.md +12 -10
  6. package/guides/query-dsl-sql.md +246 -165
  7. package/guides/telemetry-guide.md +1069 -0
  8. package/guides/zio-schema-migration.md +29 -22
  9. package/index.md +292 -50
  10. package/package.json +1 -1
  11. package/plans/config-follow-up-prs.md +188 -0
  12. package/plans/config-pr-assessment-roadmap.md +310 -0
  13. package/reference/MuxDataFlow.jsx +250 -0
  14. package/reference/async.md +651 -0
  15. package/reference/chunk.md +3533 -308
  16. package/reference/codegen/case-class.md +436 -0
  17. package/reference/codegen/emitter-config.md +383 -0
  18. package/reference/codegen/examples.md +664 -0
  19. package/reference/codegen/field.md +316 -0
  20. package/reference/codegen/index.md +317 -0
  21. package/reference/codegen/scala-emitter.md +392 -0
  22. package/reference/codegen/scala-file.md +276 -0
  23. package/reference/codegen/sealed-trait.md +408 -0
  24. package/reference/codegen/type-definition.md +340 -0
  25. package/reference/codegen/type-ref.md +201 -0
  26. package/reference/combinators.md +347 -117
  27. package/reference/config.md +158 -0
  28. package/reference/context.md +4 -4
  29. package/reference/datastar.md +346 -0
  30. package/reference/docs.md +1461 -345
  31. package/reference/endpoint/auth-type.md +146 -0
  32. package/reference/endpoint/endpoint.md +297 -0
  33. package/reference/endpoint/http-codec.md +249 -0
  34. package/reference/endpoint/index.md +825 -0
  35. package/reference/endpoint/path-codec.md +237 -0
  36. package/reference/endpoint/route-pattern.md +196 -0
  37. package/reference/endpoint/route-tree.md +111 -0
  38. package/reference/endpoint/segment-codec.md +212 -0
  39. package/reference/html.md +1120 -0
  40. package/reference/htmx/attribute-values.md +359 -0
  41. package/reference/htmx/hx-encoding.md +111 -0
  42. package/reference/htmx/hx-params.md +204 -0
  43. package/reference/htmx/hx-swap.md +276 -0
  44. package/reference/htmx/hx-sync.md +251 -0
  45. package/reference/htmx/hx-target.md +314 -0
  46. package/reference/htmx/hx-trigger.md +457 -0
  47. package/reference/htmx/hx-url-update.md +239 -0
  48. package/reference/htmx/index.md +855 -0
  49. package/reference/http-model/index.md +47 -0
  50. package/reference/http-model/model.md +1481 -0
  51. package/reference/http-model/schema.md +747 -0
  52. package/reference/maybe.md +826 -0
  53. package/reference/media-type.md +2 -2
  54. package/reference/mux.mdx +823 -0
  55. package/reference/openapi.md +1351 -0
  56. package/reference/resource-management/defer-handle.md +1 -1
  57. package/reference/resource-management/resource.md +31 -2
  58. package/reference/resource-management/scope.md +28 -12
  59. package/reference/resource-management/wire.md +3 -7
  60. package/reference/ringbuffer/MpmcDiagram.jsx +717 -0
  61. package/reference/ringbuffer/MpscDiagram.jsx +618 -0
  62. package/reference/ringbuffer/SpmcDiagram.jsx +680 -0
  63. package/reference/ringbuffer/SpscDiagram.jsx +677 -0
  64. package/reference/ringbuffer/advanced.mdx +109 -0
  65. package/reference/ringbuffer/index.mdx +145 -0
  66. package/reference/ringbuffer/mpmc.mdx +151 -0
  67. package/reference/ringbuffer/mpsc.mdx +132 -0
  68. package/reference/ringbuffer/spmc.mdx +108 -0
  69. package/reference/ringbuffer/spsc.mdx +344 -0
  70. package/reference/{allows.md → schema/allows.md} +4 -4
  71. package/reference/{binding-resolver.md → schema/binding-resolver.md} +1 -1
  72. package/reference/{binding.md → schema/binding.md} +2 -3
  73. package/reference/schema/built-in-codecs/avro.md +451 -0
  74. package/reference/schema/built-in-codecs/bson.md +480 -0
  75. package/reference/schema/built-in-codecs/csv.md +564 -0
  76. package/reference/schema/built-in-codecs/index.md +77 -0
  77. package/reference/schema/built-in-codecs/json/index.md +295 -0
  78. package/reference/schema/built-in-codecs/json/json-config.md +217 -0
  79. package/reference/{json-patch.md → schema/built-in-codecs/json/json-patch.md} +5 -5
  80. package/reference/{json-schema.md → schema/built-in-codecs/json/json-schema.md} +14 -47
  81. package/reference/schema/built-in-codecs/json/json-selection.md +322 -0
  82. package/reference/{json.md → schema/built-in-codecs/json/json.md} +32 -64
  83. package/reference/schema/built-in-codecs/messagepack.md +508 -0
  84. package/reference/schema/built-in-codecs/thrift.md +433 -0
  85. package/reference/schema/built-in-codecs/toon.md +1078 -0
  86. package/reference/{xml.md → schema/built-in-codecs/xml.md} +13 -9
  87. package/reference/schema/built-in-codecs/yaml.md +552 -0
  88. package/reference/{codec.md → schema/codec.md} +10 -10
  89. package/reference/{dynamic-optic.md → schema/dynamic-optic.md} +151 -5
  90. package/reference/{dynamic-schema.md → schema/dynamic-schema.md} +8 -8
  91. package/reference/schema/format.md +92 -0
  92. package/reference/schema/index.md +50 -0
  93. package/reference/schema/migration.md +297 -0
  94. package/reference/{modifier.md → schema/modifier.md} +58 -7
  95. package/reference/{optics.md → schema/optics.md} +2 -2
  96. package/reference/{patch.md → schema/patch.md} +1 -1
  97. package/{path-interpolator.md → reference/schema/path-interpolator.md} +165 -72
  98. package/reference/{schema-evolution → schema/schema-evolution}/as.md +8 -8
  99. package/reference/{schema-evolution → schema/schema-evolution}/index.md +2 -2
  100. package/reference/{schema-evolution → schema/schema-evolution}/into.md +8 -8
  101. package/reference/{schema-expr.md → schema/schema-expr.md} +110 -175
  102. package/reference/{schema.md → schema/schema.md} +12 -0
  103. package/reference/{structural-types.md → schema/structural-types.md} +1 -1
  104. package/reference/{type-class-derivation.md → schema/type-class-derivation.md} +63 -1
  105. package/reference/smithy.md +533 -0
  106. package/reference/sql/db-codec-deriver.md +71 -0
  107. package/reference/sql/db-codec.md +687 -0
  108. package/reference/sql/db-con.md +271 -0
  109. package/reference/sql/db-connection.md +153 -0
  110. package/reference/sql/db-param-writer.md +77 -0
  111. package/reference/sql/db-param.md +66 -0
  112. package/reference/sql/db-result-reader.md +146 -0
  113. package/reference/sql/db-tx.md +82 -0
  114. package/reference/sql/db-value.md +41 -0
  115. package/reference/sql/ddl.md +85 -0
  116. package/reference/sql/frag.md +254 -0
  117. package/reference/sql/index.md +341 -0
  118. package/reference/sql/repo.md +600 -0
  119. package/reference/sql/sql-dialect.md +73 -0
  120. package/reference/sql/sql-logger.md +62 -0
  121. package/reference/sql/sql-name-mapper.md +70 -0
  122. package/reference/sql/table-metadata.md +134 -0
  123. package/reference/sql/table.md +448 -0
  124. package/reference/sql/transactor-zio.md +399 -0
  125. package/reference/sql/transactor.md +353 -0
  126. package/reference/sql-zio.md +112 -0
  127. package/reference/streams/concurrent-operators.md +106 -0
  128. package/reference/streams/index.md +653 -0
  129. package/reference/streams/pipeline.md +718 -0
  130. package/reference/streams/reader.md +1284 -0
  131. package/reference/streams/scala-2-compatibility.md +55 -0
  132. package/reference/streams/sink.md +1426 -0
  133. package/reference/streams/stream.md +2526 -0
  134. package/reference/streams/writer.md +1045 -0
  135. package/reference/streams/zero-boxing.md +275 -0
  136. package/reference/telemetry.md +693 -0
  137. package/reference/typeid.md +5 -19
  138. package/sidebars.js +238 -43
  139. package/reference/formats.md +0 -694
  140. package/reference/http-model.md +0 -1716
  141. package/reference/streams.md +0 -989
  142. package/ringbuffer.md +0 -249
  143. /package/reference/{json-differ.md → schema/built-in-codecs/json/json-differ.md} +0 -0
  144. /package/reference/{dynamic-value.md → schema/dynamic-value.md} +0 -0
  145. /package/reference/{lazy.md → schema/lazy.md} +0 -0
  146. /package/reference/{reflect.md → schema/reflect.md} +0 -0
  147. /package/reference/{registers.md → schema/registers.md} +0 -0
  148. /package/reference/{schema-error.md → schema/schema-error.md} +0 -0
  149. /package/reference/{syntax.md → schema/syntax.md} +0 -0
  150. /package/reference/{validation.md → schema/validation.md} +0 -0
@@ -0,0 +1,564 @@
1
+ ---
2
+ id: csv
3
+ title: "CSV Codec Module"
4
+ ---
5
+
6
+ import Tabs from '@theme/Tabs';
7
+ import TabItem from '@theme/TabItem';
8
+
9
+ `zio-blocks-schema-csv` is a **schema-driven CSV codec module** for serializing and deserializing Scala types to and from CSV format. It provides RFC 4180-compliant parsing and generation with zero dependencies and support for 27 primitive types plus flat record (case class) types. Core types: `CsvCodec`, `CsvConfig`, `CsvError`, `CsvReader`, `CsvWriter`, `CsvFormat`.
10
+
11
+ The main public API is `CsvCodec[A]`, which extends `TextCodec[A]` and provides CSV-specific header support:
12
+
13
+ ```scala
14
+ import java.nio.CharBuffer
15
+ import zio.blocks.schema.SchemaError
16
+
17
+ // API signature (conceptual - simplified for clarity)
18
+ trait CsvCodec[A] {
19
+ def headerNames: IndexedSeq[String]
20
+ def encode(value: A, output: CharBuffer): Unit
21
+ def decode(input: CharBuffer): Either[SchemaError, A]
22
+ }
23
+ ```
24
+
25
+ ## Motivation
26
+
27
+ CSV is the de facto standard for tabular data exchange across systems, but parsing and serialization are often error-prone when done manually. `zio-blocks-schema-csv` eliminates this friction by deriving codec instances directly from your Scala types using ZIO Schema. You describe your data shape once, and the module handles:
28
+ - RFC 4180-compliant parsing and generation with proper quote escaping
29
+ - Precise error reporting with row/column locations
30
+ - Zero-overhead errors (no stack traces) optimized for CSV stream processing
31
+ - Cross-platform support (JVM and Scala.js)
32
+
33
+ Rather than writing custom parsers or relying on string-based configuration, you work with strongly-typed schemas that the compiler validates.
34
+
35
+ ## Installation
36
+
37
+ Add the module to your `build.sbt`:
38
+
39
+ ```sbt
40
+ libraryDependencies += "dev.zio" %% "zio-blocks-schema-csv" % "0.0.51"
41
+ ```
42
+
43
+ For Scala.js, use `%%%` instead of `%%`:
44
+
45
+ ```sbt
46
+ libraryDependencies += "dev.zio" %%% "zio-blocks-schema-csv" % "0.0.51"
47
+ ```
48
+
49
+ Supported Scala versions: 2.13.x and 3.x
50
+
51
+ ## Introduction
52
+
53
+ The module provides a complete pipeline for CSV codec derivation and usage:
54
+
55
+ 1. **Define your type** — Any Scala type with a `Schema` instance
56
+ 2. **Derive a codec** — Use `CsvFormat` to obtain a `CsvCodec[A]`
57
+ 3. **Parse or serialize** — Call `CsvCodec#decode` or `CsvCodec#encode`
58
+ 4. **Handle errors** — Catch `CsvError` with row/column location information
59
+
60
+ The derivation process is automatic for supported types (all 27 primitives and flat records). Unsupported types (sealed traits, sequences, maps) are rejected at derivation time with clear error messages.
61
+
62
+ ## How They Work Together
63
+
64
+ The CSV codec pipeline flows through these layers:
65
+
66
+ ```
67
+ 1. User defines Schema[A] for their type
68
+ ↓
69
+ 2. Schema.derive(CsvFormat) creates CsvCodec[A]
70
+ ↓
71
+ 3. CsvCodecDeriver converts Schema to codec implementation
72
+ - For primitives: type-specific encoders/decoders
73
+ - For records: field-by-field composition
74
+ ↓
75
+ 4. CsvCodec#encode writes values to CSV rows (via CsvWriter)
76
+ CsvCodec#decode reads CSV rows to values (via CsvReader)
77
+ ↓
78
+ 5. CsvReader/CsvWriter handle RFC 4180 quote escaping
79
+ CsvConfig customizes delimiters, terminators, quoting
80
+ ↓
81
+ 6. CsvError reports ParseError or TypeError with location
82
+ ```
83
+
84
+ **Typical workflow:**
85
+
86
+ A user type flows through the derivation and encoding pipeline as follows:
87
+
88
+ ```
89
+ User type (e.g., case class Person)
90
+ ↓
91
+ Schema.derived (automatic via macro)
92
+ ↓
93
+ .derive(CsvFormat) → CsvCodec[Person]
94
+ ↓
95
+ Use codec.headerNames for column names
96
+ ↓
97
+ Use codec.encode(person, buffer) to serialize
98
+ Use codec.decode(buffer) to deserialize
99
+ ↓
100
+ Handle CsvError.ParseError or TypeError on failure
101
+ ```
102
+
103
+ ## Common Patterns
104
+
105
+ This section shows 4 practical patterns for working with CSV codecs in real-world scenarios.
106
+
107
+ ### Pattern 1: Derive and Use a Simple Codec
108
+
109
+ To derive and use a CSV codec for a record type:
110
+
111
+ ```scala
112
+ import zio.blocks.schema._
113
+ import zio.blocks.schema.csv._
114
+ import java.nio.CharBuffer
115
+
116
+ case class Person(name: String, age: Int, email: String)
117
+
118
+ object Person {
119
+ implicit val schema: Schema[Person] = Schema.derived
120
+ }
121
+
122
+ val codec = Person.schema.derive(CsvFormat)
123
+ val person = Person("Alice", 30, "alice@example.com")
124
+ val buffer = CharBuffer.allocate(256)
125
+ codec.encode(person, buffer)
126
+ buffer.flip()
127
+ val encoded = buffer.toString
128
+ ```
129
+
130
+ ### Pattern 2: Customize CSV Format with CsvConfig
131
+
132
+ When you need tab-separated values (TSV) or a different delimiter, pass a custom `CsvConfig` to the derivation or directly to encoding/decoding methods.
133
+
134
+ To use a tab-separated format instead of comma-separated:
135
+
136
+ ```scala
137
+ import zio.blocks.schema._
138
+ import zio.blocks.schema.csv._
139
+
140
+ case class Record(id: Int, value: String)
141
+
142
+ object Record {
143
+ implicit val schema: Schema[Record] = Schema.derived
144
+ // Note: Schema#derive accepts only a single format argument
145
+ // TSV configuration would be set through the format's configuration API
146
+ val tsvCodec = schema.derive(CsvFormat) // See CsvConfig for available options
147
+ }
148
+ ```
149
+
150
+ ### Pattern 3: Handle CSV Errors with Location Information
151
+
152
+ CSV errors report the exact row and column where parsing or type conversion failed, allowing you to give users precise feedback.
153
+
154
+ To handle parsing errors in a user-friendly way:
155
+
156
+ ```scala
157
+ import zio.blocks.schema._
158
+ import zio.blocks.schema.csv._
159
+ import java.nio.CharBuffer
160
+
161
+ case class Employee(id: Int, name: String, salary: BigDecimal)
162
+
163
+ object Employee {
164
+ implicit val schema: Schema[Employee] = Schema.derived
165
+ }
166
+
167
+ val codec = Employee.schema.derive(CsvFormat)
168
+ val csvData = "id,name,salary\n1,Alice,invalid\n"
169
+
170
+ // Attempt to parse the CSV
171
+ val result = codec.decode(CharBuffer.wrap(csvData))
172
+
173
+ result match {
174
+ case Right(employee) => println(s"Parsed: $employee")
175
+ case Left(error) =>
176
+ // CsvError is wrapped in SchemaError
177
+ println(s"Parse error: ${error.getMessage}")
178
+ }
179
+ ```
180
+
181
+ ### Pattern 4: Working with Headers
182
+
183
+ Access the derived header names and use them to construct CSV output or validate input.
184
+
185
+ To get the column headers for a record type:
186
+
187
+ ```scala
188
+ import zio.blocks.schema._
189
+ import zio.blocks.schema.csv._
190
+
191
+ case class Product(sku: String, name: String, price: Double)
192
+
193
+ object Product {
194
+ implicit val schema: Schema[Product] = Schema.derived
195
+ }
196
+
197
+ val codec = Product.schema.derive(CsvFormat)
198
+ val headers = codec.headerNames
199
+ // headers: IndexedSeq[String] = Vector("sku", "name", "price")
200
+ ```
201
+
202
+ ## CsvCodec[A]
203
+
204
+ Abstract codec for encoding and decoding values to and from CSV format. Extends `TextCodec[A]` and provides CSV-specific header support.
205
+
206
+ ### Construction
207
+
208
+ Codecs are derived automatically from `Schema[A]` using `CsvFormat`:
209
+
210
+ ```scala
211
+ import zio.blocks.schema._
212
+ import zio.blocks.schema.csv._
213
+
214
+ case class User(id: Int, username: String)
215
+
216
+ object User {
217
+ implicit val schema: Schema[User] = Schema.derived
218
+ }
219
+
220
+ val codec: CsvCodec[User] = User.schema.derive(CsvFormat)
221
+ ```
222
+
223
+ ### Header Names
224
+
225
+ To access the CSV column headers derived from a record type:
226
+
227
+ ```scala
228
+ import zio.blocks.schema._
229
+ import zio.blocks.schema.csv._
230
+
231
+ case class Book(title: String, author: String, isbn: String)
232
+
233
+ object Book {
234
+ implicit val schema: Schema[Book] = Schema.derived
235
+ }
236
+
237
+ val codec = Book.schema.derive(CsvFormat)
238
+ val headers: IndexedSeq[String] = codec.headerNames
239
+ ```
240
+
241
+ ### Encoding Values
242
+
243
+ To serialize a value to CSV format in a `CharBuffer`:
244
+
245
+ ```scala
246
+ import zio.blocks.schema._
247
+ import zio.blocks.schema.csv._
248
+ import java.nio.CharBuffer
249
+
250
+ case class Item(name: String, quantity: Int)
251
+
252
+ object Item {
253
+ implicit val schema: Schema[Item] = Schema.derived
254
+ }
255
+
256
+ val codec = Item.schema.derive(CsvFormat)
257
+ val item = Item("Widget", 42)
258
+ val buffer = CharBuffer.allocate(512)
259
+ codec.encode(item, buffer)
260
+ buffer.flip()
261
+ val csvLine = buffer.toString
262
+ ```
263
+
264
+ ### Decoding Values
265
+
266
+ To parse CSV data from a `CharBuffer` into a value:
267
+
268
+ ```scala
269
+ import zio.blocks.schema._
270
+ import zio.blocks.schema.csv._
271
+ import java.nio.CharBuffer
272
+
273
+ case class Sales(product: String, amount: BigDecimal)
274
+
275
+ object Sales {
276
+ implicit val schema: Schema[Sales] = Schema.derived
277
+ }
278
+
279
+ val codec = Sales.schema.derive(CsvFormat)
280
+ val csvData = "product,amount\nWidget,99.99\n"
281
+ val result: Either[SchemaError, Sales] = codec.decode(CharBuffer.wrap(csvData))
282
+ ```
283
+
284
+ ---
285
+
286
+ ## CsvConfig
287
+
288
+ Configuration for CSV parsing and generation, controlling delimiters, quoting, line termination, and header handling.
289
+
290
+ ### Overview
291
+
292
+ `CsvConfig` is a case class with sensible RFC 4180 defaults. Customize it when you need different delimiters (e.g., tabs), custom line endings, or different quoting behavior.
293
+
294
+ ### Defaults and Presets
295
+
296
+ The standard RFC 4180 CSV format:
297
+
298
+ ```scala
299
+ import zio.blocks.schema.csv._
300
+
301
+ val config: CsvConfig = CsvConfig.default
302
+ // CsvConfig(',', '"', "\r\n", hasHeader = true, nullValue = "")
303
+ ```
304
+
305
+ A tab-separated values (TSV) preset with tabs as delimiters:
306
+
307
+ ```scala
308
+ import zio.blocks.schema.csv._
309
+
310
+ val tsvConfig: CsvConfig = CsvConfig.tsv
311
+ // CsvConfig('\t', '"', "\r\n", hasHeader = true, nullValue = "")
312
+ ```
313
+
314
+ ### Configuration Fields
315
+
316
+ - **`delimiter`** (default: `','`) — Character separating fields in a row
317
+ - **`quoteChar`** (default: `'"'`) — Character to quote fields containing delimiters or newlines; escapes quotes within quoted fields by doubling
318
+ - **`lineTerminator`** (default: `"\r\n"`) — Sequence terminating each row (RFC 4180 standard is CRLF)
319
+ - **`hasHeader`** (default: `true`) — Whether the first row contains column headers
320
+ - **`nullValue`** (default: `""`) — String representation for null values
321
+
322
+ ### Custom Configuration
323
+
324
+ To use a pipe-delimited format:
325
+
326
+ ```scala
327
+ import zio.blocks.schema.csv._
328
+
329
+ val customConfig = CsvConfig(
330
+ delimiter = '|',
331
+ quoteChar = '"',
332
+ lineTerminator = "\n",
333
+ hasHeader = true,
334
+ nullValue = "NULL"
335
+ )
336
+ ```
337
+
338
+ ---
339
+
340
+ ## CsvError
341
+
342
+ Sealed abstract class representing errors during CSV parsing and type conversion. Designed for high-performance CSV processing with zero-overhead exceptions (no stack traces).
343
+
344
+ ### Error Hierarchy
345
+
346
+ All CSV errors track row and column information (both 1-based) for precise error reporting.
347
+
348
+ **ParseError** — Occurs when CSV format is invalid:
349
+
350
+ ```scala
351
+ import zio.blocks.schema.csv._
352
+
353
+ val parseError = CsvError.ParseError("Unclosed quoted field", row = 2, column = 15)
354
+ ```
355
+
356
+ **TypeError** — Occurs when a field cannot be converted to the expected type:
357
+
358
+ ```scala
359
+ import zio.blocks.schema.csv._
360
+
361
+ val typeError = CsvError.TypeError(
362
+ "Invalid integer: abc",
363
+ row = 3,
364
+ column = 5,
365
+ fieldName = "age"
366
+ )
367
+ ```
368
+
369
+ ### Error Information
370
+
371
+ Both error types provide detailed context:
372
+
373
+ ```scala
374
+ import zio.blocks.schema.csv._
375
+
376
+ val error = CsvError.ParseError("Unexpected character after closing quote", row = 1, column = 10)
377
+ val message: String = error.getMessage
378
+ val row: Int = error.row
379
+ val column: Int = error.column
380
+ ```
381
+
382
+ ---
383
+
384
+ ## CsvReader
385
+
386
+ Low-level CSV row parser implementing RFC 4180 with a state machine approach. Provides stateless utility methods for parsing individual rows, headers, and complete documents.
387
+
388
+ ### Parsing a Single Row
389
+
390
+ To parse one CSV row starting at a given offset in the input:
391
+
392
+ ```scala
393
+ import zio.blocks.schema.csv._
394
+
395
+ val input = "Alice,30,alice@example.com\nBob,25,bob@example.com\n"
396
+ val config = CsvConfig.default
397
+
398
+ val result: Either[CsvError, (IndexedSeq[String], Int)] =
399
+ CsvReader.readRow(input, offset = 0, config)
400
+
401
+ result match {
402
+ case Right((fields, nextOffset)) =>
403
+ println(s"Fields: $fields")
404
+ println(s"Next offset: $nextOffset")
405
+ case Left(err) =>
406
+ println(s"Parse error: ${err.getMessage}")
407
+ }
408
+ ```
409
+
410
+ ### Parsing the Header Row
411
+
412
+ To parse just the first row as column headers:
413
+
414
+ ```scala
415
+ import zio.blocks.schema.csv._
416
+
417
+ val input = "name,age,email\nAlice,30,alice@example.com\n"
418
+ val config = CsvConfig.default
419
+
420
+ val result: Either[CsvError, (IndexedSeq[String], Int)] =
421
+ CsvReader.readHeader(input, config)
422
+ ```
423
+
424
+ ### Parsing Complete CSV
425
+
426
+ To parse a complete CSV document (header and all data rows):
427
+
428
+ ```scala
429
+ import zio.blocks.schema.csv._
430
+
431
+ val csv = "name,age\nAlice,30\nBob,25\n"
432
+ val config = CsvConfig.default
433
+
434
+ val result: Either[CsvError, (IndexedSeq[String], IndexedSeq[IndexedSeq[String]])] =
435
+ CsvReader.readAll(csv, config)
436
+
437
+ result match {
438
+ case Right((header, rows)) =>
439
+ println(s"Header: $header")
440
+ rows.foreach(row => println(s"Row: $row"))
441
+ case Left(err) =>
442
+ println(s"Parse error: ${err.getMessage}")
443
+ }
444
+ ```
445
+
446
+ ---
447
+
448
+ ## CsvWriter
449
+
450
+ Low-level CSV row serializer implementing RFC 4180 with proper field escaping.
451
+
452
+ ### Writing a Single Row
453
+
454
+ To serialize one row of fields to CSV format:
455
+
456
+ ```scala
457
+ import zio.blocks.schema.csv._
458
+
459
+ val fields: IndexedSeq[String] = Vector("Alice", "30", "alice@example.com")
460
+ val config = CsvConfig.default
461
+
462
+ val csvLine: String = CsvWriter.writeRow(fields, config)
463
+ // Result: "Alice,30,alice@example.com\r\n"
464
+ ```
465
+
466
+ ### Writing Headers
467
+
468
+ To write a header row (semantically identical to `CsvWriter#writeRow` but communicates intent):
469
+
470
+ ```scala
471
+ import zio.blocks.schema.csv._
472
+
473
+ val columnNames: IndexedSeq[String] = Vector("name", "age", "email")
474
+ val config = CsvConfig.default
475
+
476
+ val csvHeader: String = CsvWriter.writeHeader(columnNames, config)
477
+ // Result: "name,age,email\r\n"
478
+ ```
479
+
480
+ ### Writing Complete CSV
481
+
482
+ To write a complete CSV document with headers and data rows:
483
+
484
+ ```scala
485
+ import zio.blocks.schema.csv._
486
+
487
+ val header: IndexedSeq[String] = Vector("product", "quantity")
488
+ val rows: Seq[IndexedSeq[String]] = Seq(
489
+ Vector("Widget", "10"),
490
+ Vector("Gadget", "5"),
491
+ Vector("Gizmo", "8")
492
+ )
493
+ val config = CsvConfig.default
494
+
495
+ val csv: String = CsvWriter.writeAll(header, rows, config)
496
+ ```
497
+
498
+ ### RFC 4180 Escaping
499
+
500
+ `CsvWriter` automatically escapes fields according to RFC 4180:
501
+ - Fields containing the delimiter, quote character, or newlines are wrapped in quotes
502
+ - Quote characters within quoted fields are doubled (e.g., `Alice "The Expert" Smith` becomes `"Alice ""The Expert"" Smith"`)
503
+ - Fields not requiring escaping are written as-is for readability
504
+
505
+ ---
506
+
507
+ ## CsvCodecDeriver
508
+
509
+ Implements schema-driven derivation of `CsvCodec[A]` instances. Automatically handles 27 primitive types and flat record types, rejecting unsupported types (sealed traits, sequences, maps) with clear error messages.
510
+
511
+ ### Primitive Type Support
512
+
513
+ All 27 ZIO Schema primitives are supported:
514
+ - Numeric: `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `BigInt`, `BigDecimal`
515
+ - Logical: `Boolean`, `Char`, `String`
516
+ - Temporal: `Instant`, `LocalDate`, `LocalDateTime`, `LocalTime`, `Duration`, `Period`, `Year`, `YearMonth`, `MonthDay`, `Month`, `DayOfWeek`, `ZonedDateTime`, `OffsetDateTime`, `OffsetTime`, `ZoneId`, `ZoneOffset`
517
+ - Special: `UUID`, `Currency`, `Unit`
518
+
519
+ ### Record Type Support
520
+
521
+ Flat case classes (records with no variant or sequence fields) are fully supported. Each field becomes a CSV column with the field name as the header:
522
+
523
+ ```scala
524
+ import zio.blocks.schema._
525
+ import zio.blocks.schema.csv._
526
+
527
+ case class Address(street: String, city: String, zip: String)
528
+
529
+ object Address {
530
+ implicit val schema: Schema[Address] = Schema.derived
531
+ }
532
+
533
+ val codec = Address.schema.derive(CsvFormat)
534
+ val headers = codec.headerNames // Vector("street", "city", "zip")
535
+ ```
536
+
537
+ ### Unsupported Types
538
+
539
+ Attempting to derive a codec for unsupported types (sealed traits, sequences, maps, dynamic types) results in a clear compile-time or derivation-time error. The deriver rejects these to prevent silent failures in CSV processing.
540
+
541
+ ---
542
+
543
+ ## CsvFormat
544
+
545
+ Integration point with ZIO Schema's format system. Provides `TextFormat[CsvCodec]` to enable `Schema[A].derive(CsvFormat)` for any supported type.
546
+
547
+ ### Using CsvFormat
548
+
549
+ To derive a CSV codec using the standard format:
550
+
551
+ ```scala
552
+ import zio.blocks.schema._
553
+ import zio.blocks.schema.csv._
554
+
555
+ case class Sensor(id: Long, temperature: Double, humidity: Float)
556
+
557
+ object Sensor {
558
+ implicit val schema: Schema[Sensor] = Schema.derived
559
+ }
560
+
561
+ val codec = Sensor.schema.derive(CsvFormat)
562
+ ```
563
+
564
+ `CsvFormat` is a singleton object extending `TextFormat[CsvCodec]` with the MIME type `"text/csv"` and the `CsvCodecDeriver` as its derivation strategy.
@@ -0,0 +1,77 @@
1
+ ---
2
+ id: index
3
+ title: "Built-in Formats and Codecs"
4
+ sidebar_label: "Built-in Formats and Codecs"
5
+ ---
6
+
7
+ ZIO Blocks Schema provides codec derivation for multiple serialization formats. Once you have a `Schema[A]` for your data type, you can derive codecs for most formats using the unified `Schema.derive(Format)` pattern. BSON uses a different API: `BsonSchemaCodec.bsonCodec(schema)`. See the [Format documentation](../format.md) for details on how formats work.
8
+
9
+ ## Built-in Codecs
10
+
11
+ Here's a summary of the codecs currently supported by ZIO Blocks. Most codecs provide a `BinaryFormat` or `TextFormat` object that can be passed to `derive`. BSON uses a different API (see below). See the dedicated codec documentation for installation, usage examples, and detailed type mappings:
12
+
13
+ | Derivation API | Codec Type | MIME Type | Module | Documentation |
14
+ |---------------------|-----------------------|-----------------------|---------------------------------|---------------------------------|
15
+ | `JsonFormat` | `JsonCodec[A]` | `application/json` | `zio-blocks-schema` | [JSON](./json/index.md) |
16
+ | `AvroFormat` | `AvroCodec[A]` | `application/avro` | `zio-blocks-schema-avro` | [Avro](./avro.md) |
17
+ | `BsonSchemaCodec` | `BsonCodec[A]` | `application/bson` | `zio-blocks-schema-bson` | [BSON](./bson.md) |
18
+ | `CsvFormat` | `CsvCodec[A]` | `text/csv` | `zio-blocks-schema-csv` | [CSV](./csv.md) |
19
+ | `MessagePackFormat` | `MessagePackCodec[A]` | `application/msgpack` | `zio-blocks-schema-messagepack` | [MessagePack](./messagepack.md) |
20
+ | `ThriftFormat` | `ThriftCodec[A]` | `application/thrift` | `zio-blocks-schema-thrift` | [Thrift](./thrift.md) |
21
+ | `ToonFormat` | `ToonCodec[A]` | `text/toon` | `zio-blocks-schema-toon` | [TOON](./toon.md) |
22
+ | `XmlFormat` | `XmlCodec[A]` | `application/xml` | `zio-blocks-schema-xml` | [XML](./xml.md) |
23
+ | `YamlFormat` | `YamlCodec[A]` | `application/yaml` | `zio-blocks-schema-yaml` | [YAML](./yaml.md) |
24
+
25
+ ## Supported Types
26
+
27
+ Most formats support the full set of ZIO Blocks Schema primitive types. Some formats have limitations:
28
+ - **CSV** supports only flat records and primitive types (no variants, sequences, maps, or dynamic types)
29
+ - **XML** supports records, sequences, and variants with configurable discriminator strategies
30
+ - Other formats support all composite types listed below
31
+
32
+ For format-specific limitations, see the dedicated codec documentation.
33
+
34
+ **Numeric Types**:
35
+ - `Boolean`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`, `Char`
36
+ - `BigInt`, `BigDecimal`
37
+
38
+ **Text Types**:
39
+ - `String`
40
+
41
+ **Special Types**:
42
+ - `Unit`, `UUID`, `Currency`
43
+
44
+ **Java Time Types**:
45
+ - `Instant`, `LocalDate`, `LocalTime`, `LocalDateTime`
46
+ - `OffsetTime`, `OffsetDateTime`, `ZonedDateTime`
47
+ - `Duration`, `Period`
48
+ - `Year`, `YearMonth`, `MonthDay`
49
+ - `DayOfWeek`, `Month`
50
+ - `ZoneId`, `ZoneOffset`
51
+
52
+ **Composite Types**:
53
+ - Records (case classes)
54
+ - Variants (sealed traits)
55
+ - Sequences (`List`, `Vector`, `Set`, `Array`, etc.)
56
+ - Maps (`Map[K, V]`)
57
+ - Options (`Option[A]`)
58
+ - Eithers (`Either[A, B]`)
59
+ - Wrappers (newtypes)
60
+
61
+ ## Cross-Platform Support
62
+
63
+ | Format | JVM | Scala.js |
64
+ |-------------|-----|----------|
65
+ | JSON | ✓ | ✓ |
66
+ | TOON | ✓ | ✓ |
67
+ | MessagePack | ✓ | ✓ |
68
+ | CSV | ✓ | ✓ |
69
+ | XML | ✓ | ✓ |
70
+ | YAML | ✓ | ✓ |
71
+ | Avro | ✓ | ✗ |
72
+ | Thrift | ✓ | ✗ |
73
+ | BSON | ✓ | ✗ |
74
+
75
+ ## Error Handling
76
+
77
+ All formats return `Either[SchemaError, A]` for decoding operations. Errors include path information for debugging, showing exactly where in nested structures a decoding failure occurred. See individual codec documentation for format-specific error details.