Skip to content

Commit b183ecf

Browse files
committed
Include CSVEncoder in the README
1 parent c3c3393 commit b183ecf

File tree

6 files changed

+82
-25
lines changed

6 files changed

+82
-25
lines changed

README.md

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,27 +134,27 @@ A `CSVReadder` parses CSV data from a given input (`String`, or `Data`, or file)
134134

135135
`CSVReader` accepts the following configuration properties:
136136

137-
- `encoding` (default: `nil`) specify the CSV file encoding.
137+
- `encoding` (default `nil`) specify the CSV file encoding.
138138

139139
This `String.Encoding` value specify how each underlying byte is represented (e.g. `.utf8`, `.utf32littleEndian`, etc.). If it is `nil`, the library will try to figure out the file encoding through the file's [Byte Order Marker](https://en.wikipedia.org/wiki/Byte_order_mark). If the file doesn't contain a BOM, `.utf8` is presumed.
140140

141-
- `delimiters` (default: `(field: ",", row: "\n")`) specify the field and row delimiters.
141+
- `delimiters` (default `(field: ",", row: "\n")`) specify the field and row delimiters.
142142

143143
CSV fields are separated within a row with _field delimiters_ (commonly a "comma"). CSV rows are separated through _row delimiters_ (commonly a "line feed"). You can specify any unicode scalar, `String` value, or `nil` for unknown delimiters.
144144

145-
- `escapingStrategy` (default: `.doubleQuote`) specify the Unicode scalar used to escape fields.
145+
- `escapingStrategy` (default `.doubleQuote`) specify the Unicode scalar used to escape fields.
146146

147147
CSV fields can be escaped in case they contain priviledge characters, such as field/row delimiters. Commonly the escaping character is a double quote (i.e. `"`), by setting this configuration value you can change it (e.g. a single quote), or disable the escaping functionality.
148148
149-
- `headerStrategy` (default: `.none`) indicates whether the CSV data has a header row or not.
149+
- `headerStrategy` (default `.none`) indicates whether the CSV data has a header row or not.
150150
151151
CSV files may contain an optional header row at the very beginning. This configuration value lets you specify whether the file has a header row or not, or whether you want the library to figure it out.
152152
153-
- `trimStrategy` (default: empty set) trims the given characters at the beginning and end of each parsed field.
153+
- `trimStrategy` (default empty set) trims the given characters at the beginning and end of each parsed field.
154154
155155
The trim characters are applied for the escaped and unescaped fields. The set cannot include any of the delimiter characters or the escaping scalar. If so, an error will be thrown during initialization.
156156
157-
- `presample` (default: `false`) indicates whether the CSV data should be completely loaded into memory before parsing begins.
157+
- `presample` (default `false`) indicates whether the CSV data should be completely loaded into memory before parsing begins.
158158
159159
Loading all data into memory may provide faster iteration for small to medium size files, since you get rid of the overhead of managing an `InputStream`.
160160
@@ -236,23 +236,23 @@ A `CSVWriter` encodes CSV information into a specified target (i.e. a `String`,
236236
237237
`CSVWriter` accepts the following configuration properties:
238238
239-
- `delimiters` (default: `(field: ",", row: "\n")`) specify the field and row delimiters.
239+
- `delimiters` (default `(field: ",", row: "\n")`) specify the field and row delimiters.
240240
241241
CSV fields are separated within a row with _field delimiters_ (commonly a "comma"). CSV rows are separated through _row delimiters_ (commonly a "line feed"). You can specify any unicode scalar, `String` value, or `nil` for unknown delimiters.
242242
243-
- `escapingStrategy` (default: `.doubleQuote`) specify the Unicode scalar used to escape fields.
243+
- `escapingStrategy` (default `.doubleQuote`) specify the Unicode scalar used to escape fields.
244244
245245
CSV fields can be escaped in case they contain priviledge characters, such as field/row delimiters. Commonly the escaping character is a double quote (i.e. `"`), by setting this configuration value you can change it (e.g. a single quote), or disable the escaping functionality.
246246

247-
- `headers` (default: `[]`) indicates whether the CSV data has a header row or not.
247+
- `headers` (default `[]`) indicates whether the CSV data has a header row or not.
248248

249249
CSV files may contain an optional header row at the very beginning. If this configuration value is empty, no header row is writen.
250250

251-
- `encoding` (default: `nil`) specify the CSV file encoding.
251+
- `encoding` (default `nil`) specify the CSV file encoding.
252252

253253
This `String.Encoding` value specify how each underlying byte is represented (e.g. `.utf8`, `.utf32littleEndian`, etc.). If it is `nil`, the library will try to figure out the file encoding through the file's [Byte Order Marker](https://en.wikipedia.org/wiki/Byte_order_mark). If the file doesn't contain a BOM, `.utf8` is presumed.
254254

255-
- `bomStrategy` (default: `.convention`) indicates whether a Byte Order Marker will be included at the beginning of the CSV representation.
255+
- `bomStrategy` (default `.convention`) indicates whether a Byte Order Marker will be included at the beginning of the CSV representation.
256256

257257
The OS convention is that BOMs are never writen, except when `.utf16`, `.utf32`, or `.unicode` string encodings are specified. You could however indicate that you always want the BOM writen (`.always`) or that is never writen (`.never`).
258258

@@ -312,21 +312,30 @@ let decoder = CSVDecoder()
312312
let result = try decoder.decode(CustomType.self, from: data)
313313
```
314314

315+
`CSVDecoder` can decode CSVs represented as a `Data` blob, a `String`, or an actual file in the file system.
316+
317+
```swift
318+
let decoder = CSVDecoder { $0.bufferingStrategy = .unfulfilled }
319+
let content: [Student] = try decoder([Student].self, from: URL("~/Desktop/Student.csv"))
320+
```
321+
322+
If you are dealing with a big CSV file, it is preferred to used direct file decoding and a `.sequential` or `.unfulfilled` buffering strategy, since then memory usage is drastically reduced.
323+
315324
### Decoder configuration
316325

317326
The decoding process can be tweaked by specifying configuration values at initialization time. `CSVDecoder` accepts the [same configuration values as `CSVReader`](#Reader-configuration) plus the following ones:
318327

319-
- `floatStrategy` (default: `.throw`) defines how to deal with non-conforming floating-point numbers (such as `NaN`, or `+Infinity`).
328+
- `floatStrategy` (default `.throw`) defines how to deal with non-conforming floating-point numbers (e.g. `NaN`).
320329

321-
- `decimalStrategy` (default: `.locale(nil)`) indicates how decimal numbers are decoded (from `String` to `Decimal` value).
330+
- `decimalStrategy` (default `.locale`) indicates how strings are decoded to `Decimal` values.
322331

323-
- `dataStrategy` (default: `.deferredToDate`) specify the strategy to use when decoding dates.
332+
- `dataStrategy` (default `.deferredToDate`) specify how strings are decoded to `Date` values.
324333

325-
- `dataStrategy` (default: `.base64`) specify the strategy to use when decoding data blobs.
334+
- `dataStrategy` (default `.base64`) indicates how strings are decoded to `Data` values.
326335

327-
- `bufferingStrategy` (default: `.keepAll`) tells the decoder how to cache CSV rows.
336+
- `bufferingStrategy` (default `.keepAll`) controls the behavior of `KeyedDecodingContainer`s.
328337

329-
Caching rows allow random access through `KeyedDecodingContainer`s. For more information check the `DecodingBuffer` strategy definition.
338+
Selecting a buffering strategy directly affect the the decoding performance and the amount of memory used during the process. For more information check this README's [Tips using `Codable`](#Tips-using-codable) section and the [`Strategy.DecodingBuffer` definition](sources/Codable/Decodable/DecodingStrategy.swift).
330339

331340
The configuration values can be set during `CSVDecoder` initialization or at any point before the `decode` function is called.
332341

@@ -338,8 +347,8 @@ let decoder = CSVDecoder {
338347
$0.bufferingStrategy = .keepAll
339348
}
340349

341-
decoder.decimalStratey = .custom {
342-
let value = try Float(from: $0)
350+
decoder.decimalStratey = .custom { (decoder) in
351+
let value = try Float(from: decoder)
343352
return Decimal(value)
344353
}
345354
```
@@ -348,7 +357,55 @@ decoder.decimalStratey = .custom {
348357

349358
<details><summary><code>CSVEncoder</code>.</summary><p>
350359

351-
#warning("TODO:")
360+
`CSVEncoder` transforms Swift types conforming to `Encodable` into CSV data. The encoding process is very simple and it only requires creating an encoding instance and call its `encode` function passing the `Encodable` value.
361+
362+
```swift
363+
let encoder = CSVEncoder()
364+
let data: Data = try encoder.encode(value)
365+
```
366+
367+
The `Encoder`'s `encode()` function creates a CSV file as a `Data` blob, a `String`, or an actual file in the file system.
368+
369+
```swift
370+
let encoder = CSVEncoder { $0.bufferingStrategy = .sequential }
371+
try encoder.encode(value, into: URL("~/Desktop/Students.csv"))
372+
```
373+
374+
If you are dealing with a big CSV content, it is preferred to use direct file encoding and a `.sequential` or `.unfulfilled` buffering strategy, since then memory usage is drastically reduced.
375+
376+
### Encoder configuration
377+
378+
The encoding process can be tweaked by specifying configuration values. `CSVEncoder` accepts the [same configuration values as `CSVWRiter`](#Writer-configuration) plus the following ones:
379+
380+
- `floatStrategy` (default `.throw`) defines how to deal with non-conforming floating-point numbers (e.g. `NaN`).
381+
382+
- `decimalStrategy` (default `.locale`) indicates how decimal numbers are encoded to `String` values.
383+
384+
- `dateStrategy` (default `.deferredToDate`) specify how dates are encoded to `String` values.
385+
386+
- `dataStrategy` (default `.base64`) indicates how data blobs are encoded to `String` values.
387+
388+
- `bufferingStrategy` (default `.keepAll`) controls the behavior of `KeyedEncodingContainer`s.
389+
390+
Selecting a buffering strategy directly affect the encoding performance and the amount of memory used during the process. For more information check this README's [Tips using `Codable`](#Tips-using-codable) section and the [`Strategy.EncodingBuffer` definition](sources/Codable/Encodable/EncodingStrategy.swift).
391+
392+
The configuration values can be set during `CSVEncoder` initialization or at any point before the `encode` function is called.
393+
394+
```swift
395+
let encoder = CSVEncoder {
396+
$0.header = ["name", "age", "hasPet"]
397+
$0.delimiters = (field: ";", row: "\r\n")
398+
$0.dateStrategy = .iso8601
399+
$0.bufferingStrategy = .sequential
400+
}
401+
402+
encoder.floatStrategy = .convert(positiveInfinity: "", negativeInfinity: "-∞", nan: "")
403+
encoder.dataStrategy = .custom { (data, encoder) in
404+
let string = customTransformation(data)
405+
var container = try encoder.singleValueContainer()
406+
try container.encode(string)
407+
}
408+
```
352409

353410
</p></details>
354411
</ul>

0 commit comments

Comments
 (0)