adds ‘delimiter’ parameter to decode functions

adds a ‘delimiter’ parameter to decoding functions to support other delimiters like “\t”. Where these delimiter parameters have been added a default has been set to “,” to maintain the current functionality.
This commit is contained in:
Justin 2019-04-28 15:13:49 -06:00
parent caad9866a8
commit 19f58f47bd
3 changed files with 16 additions and 14 deletions

View File

@ -199,7 +199,7 @@ public final class CSVSyncDecoder {
/// - Returns: An array of `D` instances, decoded from the data passed in.
///
/// - Throws: Errors that occur during the decoding proccess.
public func decode<D>(_ type: D.Type = D.self, from data: Data)throws -> [D] where D: Decodable {
public func decode<D>(_ type: D.Type = D.self, from data: Data, delimiter: Character = ",")throws -> [D] where D: Decodable {
var result: [D] = []
result.reserveCapacity(data.lazy.split(separator: "\n").count)
@ -211,7 +211,7 @@ public final class CSVSyncDecoder {
result.append(typed)
}
try decoder.decode(Array(data), length: data.count)
try decoder.decode(Array(data), length: data.count, delimiter: delimiter)
return result
}
@ -260,7 +260,7 @@ public final class CSVAsyncDecoder {
///
/// - Parameter data: A section of the CSV document to decode.
/// - Throws: Errors that occur during the decoding process.
public func decode<C>(_ data: C)throws where C: Collection, C.Element == UInt8 {
try self.rowDecoder.decode(Array(data), length: self.length)
public func decode<C>(_ data: C, delimiter: Character = ",")throws where C: Collection, C.Element == UInt8 {
try self.rowDecoder.decode(Array(data), length: self.length, delimiter: delimiter)
}
}

View File

@ -69,8 +69,8 @@ internal final class AsyncDecoder: Decoder {
return try AsyncSingleValueDecoder(path: self.codingPath, decoder: self)
}
func decode(_ data: [UInt8], length: Int)throws {
try self.handler.parse(data, length: length).get()
func decode(_ data: [UInt8], length: Int, delimiter: Character = ",")throws {
try self.handler.parse(data, length: length, delimiter: delimiter).get()
}
}
@ -101,7 +101,7 @@ internal final class AsyncDecoderHandler {
}
}
func parse(_ bytes: [UInt8], length: Int) -> Result<Void, ErrorList> {
return self.parser.parse(bytes, length: length)
func parse(_ bytes: [UInt8], length: Int, delimiter: Character = ",") -> Result<Void, ErrorList> {
return self.parser.parse(bytes, length: length, delimiter: delimiter)
}
}

View File

@ -1,5 +1,6 @@
import Foundation
// '\t' => 9
// '\n' => 10
// '\r' => 13
// '"' => 34
@ -105,12 +106,13 @@ public struct Parser {
/// - Returns: A `Result` instance that will have a `.failure` case with all the errors thrown from
/// the registered callbacks. If there are no errors, then the result will be a `.success` case.
@discardableResult
public mutating func parse(_ data: [UInt8], length: Int? = nil) -> Result<Void, ErrorList> {
public mutating func parse(_ data: [UInt8], length: Int? = nil, delimiter: Character = ",") -> Result<Void, ErrorList> {
var currentCell: [UInt8] = self.state.store
var index = data.startIndex
var updateState = false
var errors = ErrorList()
var slice: (start: Int, end: Int) = (index, index)
let delimiterASCII = delimiter.asciiValue
while index < data.endIndex {
let byte = data[index]
@ -138,7 +140,7 @@ public struct Parser {
if self.state.position == .headers { updateState = true }
fallthrough
}
case 44:
case delimiterASCII:
if self.state.inQuotes {
slice.end += 1
} else {
@ -201,7 +203,7 @@ public final class SyncParser {
/// - Parameter data: The CSV data to parse.
/// - Returns: A dictionary containing the parsed CSV data. The keys are the column names
/// and the values are the column cells. A `nil` value is an empty cell.
public func parse(_ data: [UInt8]) -> [[UInt8]: [[UInt8]?]] {
public func parse(_ data: [UInt8], delimiter: Character = ",") -> [[UInt8]: [[UInt8]?]] {
var results: [[UInt8]: [[UInt8]?]] = [:]
var parser = Parser(
onHeader: { header in
@ -212,7 +214,7 @@ public final class SyncParser {
}
)
parser.parse(data)
parser.parse(data, delimiter: delimiter)
return results
}
@ -221,7 +223,7 @@ public final class SyncParser {
/// - Parameter data: The CSV data to parse.
/// - Returns: A dictionary containing the parsed CSV data. The keys are the column names
/// and the values are the column cells. A `nil` value is an empty cell.
public func parse(_ data: String) -> [String: [String?]] {
public func parse(_ data: String, delimiter: Character = ",") -> [String: [String?]] {
var results: [String: [String?]] = [:]
var parser = Parser(
onHeader: { header in
@ -234,7 +236,7 @@ public final class SyncParser {
}
)
parser.parse(Array(data.utf8))
parser.parse(Array(data.utf8), delimiter: delimiter)
return results
}
}