Skip to content

Commit 5ae5412

Browse files
committed
Prepare 0.5.2 release
1 parent c9cbe41 commit 5ae5412

16 files changed

+360
-220
lines changed

CodableCSV.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'CodableCSV'
3-
s.version = '0.5.1'
3+
s.version = '0.5.2'
44
s.summary = "Read and write CSV files row-by-row or through Swift's Codable interface."
55

66
s.homepage = 'https://github.com/dehesa/CodableCSV'

Package.swift

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,7 @@ let package = Package(
1111
],
1212
dependencies: [],
1313
targets: [
14-
.target(
15-
name: "CodableCSV",
16-
dependencies: [],
17-
path: "sources"),
18-
.testTarget(
19-
name: "CodableCSVTests",
20-
dependencies: ["CodableCSV"],
21-
path: "tests"),
14+
.target(name: "CodableCSV", dependencies: [], path: "sources"),
15+
.testTarget(name: "CodableCSVTests", dependencies: ["CodableCSV"], path: "tests"),
2216
]
2317
)

README.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ A `CSVReadder` parses CSV data from a given input (`String`, or `Data`, or file)
8080

8181
```swift
8282
let data: Data = ...
83-
let result = try CSVReader.parse(input: data)
83+
let result = try CSVReader.decode(input: data)
8484

8585
// `result` lets you access the CSV headers, all CSV rows, or access a specific row/record. For example:
8686
let headers = result.headers // [String]
@@ -100,23 +100,23 @@ A `CSVReadder` parses CSV data from a given input (`String`, or `Data`, or file)
100100
let reader = try CSVReader(input: string) { $0.headerStrategy = .firstLine }
101101

102102
let headers = reader.headers // ["numA", "numB", "numC"]
103-
let rowA = try reader.parseRow() // ["1", "2", "3"]
104-
let rowB = try reader.parseRow() // ["4", "5", "6"]
103+
let rowA = try reader.readRow() // ["1", "2", "3"]
104+
let rowB = try reader.readRow() // ["4", "5", "6"]
105105
```
106106

107-
Alternatively you can use the `parseRecord()` function which also returns the next CSV row, but it wraps the result in a convenience structure. This structure lets you access each field with the header name (as long as the `headerStrategy` is marked with `.firstLine`).
107+
Alternatively you can use the `readRecord()` function which also returns the next CSV row, but it wraps the result in a convenience structure. This structure lets you access each field with the header name (as long as the `headerStrategy` is marked with `.firstLine`).
108108

109109
```swift
110110
let reader = try CSVReader(input: string) { $0.headerStrategy = .firstLine }
111111

112112
let headers = reader.headers // ["numA", "numB", "numC"]
113113

114-
let recordA = try reader.parseRecord()
114+
let recordA = try reader.readRecord()
115115
let rowA = recordA.row // ["1", "2", "3"]
116116
let firstField = recordA[0] // "1"
117117
let secondField = recordA["numB"] // "2"
118118

119-
let recordB = try reader.parseRecord()
119+
let recordB = try reader.readRecord()
120120
```
121121

122122
- `Sequence` syntax parsing.
@@ -128,7 +128,7 @@ A `CSVReadder` parses CSV data from a given input (`String`, or `Data`, or file)
128128
}
129129
```
130130

131-
Please note the `Sequence` syntax (i.e. `IteratorProtocol`) doesn't throw errors; therefore if the CSV data is invalid, the previous code will crash. If you don't control the CSV data origin, use `parseRow()` instead.
131+
Please note the `Sequence` syntax (i.e. `IteratorProtocol`) doesn't throw errors; therefore if the CSV data is invalid, the previous code will crash. If you don't control the CSV data origin, use `readRow()` instead.
132132

133133
### Reader configuration
134134

@@ -315,11 +315,11 @@ let result = try decoder.decode(CustomType.self, from: data)
315315
`CSVDecoder` can decode CSVs represented as a `Data` blob, a `String`, or an actual file in the file system.
316316
317317
```swift
318-
let decoder = CSVDecoder { $0.bufferingStrategy = .assembled }
318+
let decoder = CSVDecoder { $0.bufferingStrategy = .sequential }
319319
let content: [Student] = try decoder([Student].self, from: URL("~/Desktop/Student.csv"))
320320
```
321321
322-
If you are dealing with a big CSV file, it is preferred to used direct file decoding, a `.sequential` or `.assembled` buffering strategy, and set *presampling* to false; since then memory usage is drastically reduced.
322+
If you are dealing with a big CSV file, it is preferred to used direct file decoding, a `.sequential` or `.unrequested` buffering strategy, and set *presampling* to false; since then memory usage is drastically reduced.
323323
324324
### Decoder configuration
325325

sources/Active/Reader/Reader.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,20 +65,20 @@ public final class CSVReader: IteratorProtocol, Sequence {
6565

6666
extension CSVReader {
6767
/// Advances to the next row and returns it, or `nil` if no next row exists.
68-
/// - warning: If the CSV file being parsed contains invalid characters, this function will crash. For safer parsing use `parseRow()`.
69-
/// - seealso: parseRow()
68+
/// - warning: If the CSV file being parsed contains invalid characters, this function will crash. For safer parsing use `readRow()`.
69+
/// - seealso: readRow()
7070
@inlinable public func next() -> [String]? {
71-
return try! self.parseRow()
71+
return try! self.readRow()
7272
}
7373

7474
/// Parses a CSV row and wraps it in a convenience structure giving accesses to fields through header titles/names.
7575
///
7676
/// Since CSV parsing is sequential, if a previous call of this function encountered an error, subsequent calls will throw the same error.
7777
/// - throws: `CSVError<CSVReader>` exclusively.
7878
/// - returns: A record structure or `nil` if there isn't anything else to parse. If a record is returned there shall always be at least one field.
79-
/// - seealso: parseRow()
80-
public func parseRecord() throws -> Record? {
81-
guard let row = try self.parseRow() else { return nil }
79+
/// - seealso: readRow()
80+
public func readRecord() throws -> Record? {
81+
guard let row = try self.readRow() else { return nil }
8282

8383
let lookup: [Int:Int]
8484
if let l = self.headerLookup {
@@ -96,7 +96,7 @@ extension CSVReader {
9696
/// Since CSV parsing is sequential, if a previous call of this function encountered an error, subsequent calls will throw the same error.
9797
/// - throws: `CSVError<CSVReader>` exclusively.
9898
/// - returns: The row's fields or `nil` if there isn't anything else to parse. The row will never be an empty array.
99-
public func parseRow() throws -> [String]? {
99+
public func readRow() throws -> [String]? {
100100
switch self.status {
101101
case .active: break
102102
case .finished: return nil

sources/Active/Reader/ReaderAPI.swift

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extension CSVReader {
1010
let decoder = CSVReader.makeDecoder(from: input.unicodeScalars.makeIterator())
1111
try self.init(configuration: configuration, buffer: buffer, decoder: decoder)
1212
}
13-
13+
1414
/// Creates a reader instance that will be used to parse the given data blob.
1515
///
1616
/// If the configuration's encoding hasn't been set and the input data doesn't contain a Byte Order Marker (BOM), UTF8 is presumed.
@@ -35,7 +35,7 @@ extension CSVReader {
3535
try self.init(configuration: configuration, buffer: buffer, decoder: decoder)
3636
}
3737
}
38-
38+
3939
/// Creates a reader instance that will be used to parse the given CSV file.
4040
///
4141
/// If the configuration's encoding hasn't been set and the input data doesn't contain a Byte Order Marker (BOM), UTF8 is presumed.
@@ -84,7 +84,7 @@ extension CSVReader {
8484
setter(&configuration)
8585
try self.init(input: input, configuration: configuration)
8686
}
87-
87+
8888
/// Creates a reader instance that will be used to parse the given data blob.
8989
/// - parameter input: A data blob containing CSV formatted data.
9090
/// - parameter setter: Closure receiving the default parsing configuration values and letting you change them.
@@ -95,7 +95,7 @@ extension CSVReader {
9595
setter(&configuration)
9696
try self.init(input: input, configuration: configuration)
9797
}
98-
98+
9999
/// Creates a reader instance that will be used to parse the given CSV file.
100100
/// - parameter input: The URL indicating the location of the file to be parsed.
101101
/// - parameter setter: Closure receiving the default parsing configuration values and letting you change them.
@@ -116,46 +116,46 @@ extension CSVReader {
116116
/// - parameter configuration: Recipe detailing how to parse the CSV data (i.e. delimiters, date strategy, etc.).
117117
/// - throws: `CSVError<CSVReader>` exclusively.
118118
/// - returns: Tuple with the CSV headers (empty if none) and all records within the CSV file.
119-
public static func parse<S>(input: S, configuration: Configuration = .init()) throws -> Output where S:StringProtocol {
119+
public static func decode<S>(input: S, configuration: Configuration = .init()) throws -> Output where S:StringProtocol {
120120
let reader = try CSVReader(input: input, configuration: configuration)
121121
let lookup = try reader.headers.lookupDictionary(onCollision: Error.invalidHashableHeader)
122122

123123
var result: [[String]] = .init()
124-
while let row = try reader.parseRow() {
124+
while let row = try reader.readRow() {
125125
result.append(row)
126126
}
127127

128128
return .init(headers: reader.headers, rows: result, lookup: lookup)
129129
}
130-
130+
131131
/// Reads a blob of data using the encoding provided as argument and returns the CSV headers (if any) and all the CSV records.
132132
/// - parameter input: A blob of data containing CSV formatted data.
133133
/// - parameter configuration: Recipe detailing how to parse the CSV data (i.e. delimiters, date strategy, etc.).
134134
/// - throws: `CSVError<CSVReader>` exclusively.
135135
/// - returns: Tuple with the CSV headers (empty if none) and all records within the CSV file.
136-
public static func parse(input: Data, configuration: Configuration = .init()) throws -> Output {
136+
public static func decode(input: Data, configuration: Configuration = .init()) throws -> Output {
137137
let reader = try CSVReader(input: input, configuration: configuration)
138138
let lookup = try reader.headers.lookupDictionary(onCollision: Error.invalidHashableHeader)
139139

140140
var result: [[String]] = .init()
141-
while let row = try reader.parseRow() {
141+
while let row = try reader.readRow() {
142142
result.append(row)
143143
}
144144

145145
return .init(headers: reader.headers, rows: result, lookup: lookup)
146146
}
147-
147+
148148
/// Reads a CSV file using the provided encoding and returns the CSV headers (if any) and all the CSV records.
149149
/// - parameter input: The URL indicating the location of the file to be parsed.
150150
/// - parameter configuration: Recipe detailing how to parse the CSV data (i.e. delimiters, date strategy, etc.).
151151
/// - throws: `CSVError<CSVReader>` exclusively.
152152
/// - returns: Tuple with the CSV headers (empty if none) and all records within the CSV file.
153-
public static func parse(input: URL, configuration: Configuration = .init()) throws -> Output {
153+
public static func decode(input: URL, configuration: Configuration = .init()) throws -> Output {
154154
let reader = try CSVReader(input: input, configuration: configuration)
155155
let lookup = try reader.headers.lookupDictionary(onCollision: Error.invalidHashableHeader)
156156

157157
var result: [[String]] = .init()
158-
while let row = try reader.parseRow() {
158+
while let row = try reader.readRow() {
159159
result.append(row)
160160
}
161161

@@ -170,10 +170,10 @@ extension CSVReader {
170170
/// - parameter configuration: Default configuration values for the `CSVReader`.
171171
/// - throws: `CSVError<CSVReader>` exclusively.
172172
/// - returns: Tuple with the CSV headers (empty if none) and all records within the CSV file.
173-
@inlinable public static func parse<S>(input: S, setter: (_ configuration: inout Configuration)->Void) throws -> Output where S:StringProtocol {
173+
@inlinable public static func decode<S>(input: S, setter: (_ configuration: inout Configuration)->Void) throws -> Output where S:StringProtocol {
174174
var configuration = Configuration()
175175
setter(&configuration)
176-
return try CSVReader.parse(input: input, configuration: configuration)
176+
return try CSVReader.decode(input: input, configuration: configuration)
177177
}
178178

179179
/// Reads a blob of data using the encoding provided as argument and returns the CSV headers (if any) and all the CSV records.
@@ -182,10 +182,10 @@ extension CSVReader {
182182
/// - parameter configuration: Default configuration values for the `CSVReader`.
183183
/// - throws: `CSVError<CSVReader>` exclusively.
184184
/// - returns: Tuple with the CSV headers (empty if none) and all records within the CSV file.
185-
@inlinable public static func parse(input: Data, setter: (_ configuration: inout Configuration)->Void) throws -> Output {
185+
@inlinable public static func decode(input: Data, setter: (_ configuration: inout Configuration)->Void) throws -> Output {
186186
var configuration = Configuration()
187187
setter(&configuration)
188-
return try CSVReader.parse(input: input, configuration: configuration)
188+
return try CSVReader.decode(input: input, configuration: configuration)
189189
}
190190

191191
/// Reads a CSV file using the provided encoding and returns the CSV headers (if any) and all the CSV records.
@@ -194,10 +194,10 @@ extension CSVReader {
194194
/// - parameter configuration: Default configuration values for the `CSVReader`.
195195
/// - throws: `CSVError<CSVReader>` exclusively.
196196
/// - returns: Tuple with the CSV headers (empty if none) and all records within the CSV file.
197-
@inlinable public static func parse(input: URL, setter: (_ configuration: inout Configuration)->Void) throws -> Output {
197+
@inlinable public static func decode(input: URL, setter: (_ configuration: inout Configuration)->Void) throws -> Output {
198198
var configuration = Configuration()
199199
setter(&configuration)
200-
return try CSVReader.parse(input: input, configuration: configuration)
200+
return try CSVReader.decode(input: input, configuration: configuration)
201201
}
202202
}
203203

@@ -227,3 +227,47 @@ fileprivate extension CSVReader.Error {
227227
help: "Request a row instead of a record.")
228228
}
229229
}
230+
231+
// MARK: - Deprecations
232+
233+
extension CSVReader {
234+
@available(*, deprecated, renamed: "readRecord()")
235+
public func parseRecord() throws -> Record? {
236+
try self.readRecord()
237+
}
238+
239+
@available(*, deprecated, renamed: "readRow()")
240+
public func parseRow() throws -> [String]? {
241+
try self.readRow()
242+
}
243+
244+
@available(*, deprecated, renamed: "decode(input:configuration:)")
245+
public static func parse<S>(input: S, configuration: Configuration = .init()) throws -> Output where S:StringProtocol {
246+
try self.decode(input: input, configuration: configuration)
247+
}
248+
249+
@available(*, deprecated, renamed: "decode(rows:into:configuration:)")
250+
public static func parse(input: Data, configuration: Configuration = .init()) throws -> Output {
251+
try self.decode(input: input, configuration: configuration)
252+
}
253+
254+
@available(*, deprecated, renamed: "decode(rows:into:configuration:)")
255+
public static func parse(input: URL, configuration: Configuration = .init()) throws -> Output {
256+
try self.decode(input: input, configuration: configuration)
257+
}
258+
259+
@available(*, deprecated, renamed: "decode(rows:setter:)")
260+
public static func parse<S>(input: S, setter: (_ configuration: inout Configuration)->Void) throws -> Output where S:StringProtocol {
261+
try self.decode(input: input, setter: setter)
262+
}
263+
264+
@available(*, deprecated, renamed: "decode(rows:into:setter:)")
265+
public static func parse(input: Data, setter: (_ configuration: inout Configuration)->Void) throws -> Output {
266+
try self.decode(input: input, setter: setter)
267+
}
268+
269+
@available(*, deprecated, renamed: "decode(rows:into:append:setter:)")
270+
public static func parse(input: URL, setter: (_ configuration: inout Configuration)->Void) throws -> Output {
271+
try self.decode(input: input, setter: setter)
272+
}
273+
}

sources/Active/Writer/WriterAPI.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ fileprivate extension CSVWriter.Error {
164164
}
165165
}
166166

167-
// MARK: -
167+
// MARK: - Deprecations
168168

169169
extension CSVWriter {
170170
@available(*, deprecated, renamed: "encode(rows:configuration:)")

sources/Codable/Decodable/Containers/SingleValueDecodingContainer.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -237,17 +237,17 @@ private extension ShadowDecoder.SingleValueContainer {
237237

238238
switch self.focus {
239239
case .field(let rowIndex, let fieldIndex):
240-
let string = try source.field(at: rowIndex, fieldIndex)
240+
let string = try source.field(rowIndex, fieldIndex)
241241
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath)
242242
case .row(let rowIndex):
243243
// Values are only allowed to be decoded directly from a single value container in "row level" if the CSV has single column rows.
244244
guard source.numExpectedFields == 1 else { throw DecodingError.invalidNestedRequired(codingPath: self.codingPath) }
245-
let string = try source.field(at: rowIndex, 0)
245+
let string = try source.field(rowIndex, 0)
246246
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath + [IndexKey(0)])
247247
case .file:
248248
// Values are only allowed to be decoded directly from a single value container in "file level" if the CSV file has a single row with a single column.
249249
if source.isRowAtEnd(index: 1), source.numExpectedFields == 1 {
250-
let string = try self.decoder.source.field(at: 0, 0)
250+
let string = try self.decoder.source.field(0, 0)
251251
return try transform(string) ?! DecodingError.invalid(type: T.self, string: string, codingPath: self.codingPath + [IndexKey(0), IndexKey(0)])
252252
} else {
253253
throw DecodingError.invalidNestedRequired(codingPath: self.codingPath)

0 commit comments

Comments
 (0)