-
Notifications
You must be signed in to change notification settings - Fork 75
Expand file tree
/
Copy pathDecoder.swift
More file actions
111 lines (98 loc) · 5.74 KB
/
Decoder.swift
File metadata and controls
111 lines (98 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import Foundation
/// Instances of this class are capable of decoding CSV files as described by the `Codable` protocol.
@dynamicMemberLookup open class CSVDecoder {
/// Wrap all configurations in a single easy-to-use structure.
private final var _configuration: Configuration
/// A dictionary you use to customize the decoding process by providing contextual information.
open var userInfo: [CodingUserInfoKey:Any]
/// Creates a CSV decoder with tthe default configuration values.
/// - parameter configuration: Configuration values for the decoding process.
public init(configuration: Configuration = Configuration()) {
self._configuration = configuration
self.userInfo = Dictionary()
}
/// Creates a CSV decoder and passes the default configuration values to the closure.
/// - parameter configuration: A closure receiving the default configuration values and returning (by `inout`) a tweaked version of them.
@inlinable public convenience init(configuration: (inout Configuration)->Void) {
var config = Configuration()
configuration(&config)
self.init(configuration: config)
}
/// Gives direct access to all the decoder's configuration values.
/// - parameter member: Writable key path for the decoder's configuration value.
public final subscript<V>(dynamicMember member: WritableKeyPath<CSVDecoder.Configuration,V>) -> V {
get { self._configuration[keyPath: member] }
set { self._configuration[keyPath: member] = newValue }
}
}
extension CSVDecoder {
/// Returns a value of the type you specify, decoded from a CSV file (given as a `Data` blob).
/// - parameter type: The type of the value to decode from the supplied file.
/// - parameter data: The data blob representing a CSV file.
public func decode<T:Decodable>(_ type: T.Type, from data: Data) throws -> T {
let reader = try CSVReader(input: data, configuration: self._configuration.readerConfiguration)
return try withExtendedLifetime(ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)) {
try T(from: ShadowDecoder(source: .passUnretained($0), codingPath: []))
}
}
/// Returns a value of the type you specify, decoded from a CSV file (given as a `String`).
/// - parameter type: The type of the value to decode from the supplied file.
/// - parameter string: A Swift string representing a CSV file.
public func decode<T:Decodable>(_ type: T.Type, from string: String) throws -> T {
let reader = try CSVReader(input: string, configuration: self._configuration.readerConfiguration)
return try withExtendedLifetime(ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)) {
try T(from: ShadowDecoder(source: .passUnretained($0), codingPath: []))
}
}
/// Returns a value of the type you specify, decoded from a CSV file (being pointed by the url).
/// - parameter type: The type of the value to decode from the supplied file.
/// - parameter url: The URL pointing to the file to decode.
public func decode<T:Decodable>(_ type: T.Type, from url: URL) throws -> T {
let reader = try CSVReader(input: url, configuration: self._configuration.readerConfiguration)
return try withExtendedLifetime(ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)) {
try T(from: ShadowDecoder(source: .passUnretained($0), codingPath: []))
}
}
/// Returns a value of the type you specify, decoded from a CSV file (provided by the input stream).
/// - parameter type: The type of the value to decode from the supplied file.
/// - parameter stream: The input stream providing the raw bytes.
public func decode<T:Decodable>(_ type: T.Type, from stream: InputStream) throws -> T {
let reader = try CSVReader(input: stream, configuration: self._configuration.readerConfiguration)
return try withExtendedLifetime(ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)) {
try T(from: ShadowDecoder(source: .passUnretained($0), codingPath: []))
}
}
}
extension CSVDecoder {
/// Returns a sequence for decoding row-by-row from a CSV file (given as a `Data` blob).
/// - parameter data: The data blob representing a CSV file.
/// - throws: `CSVError<CSVReader>` exclusively.
public func lazy(from data: Data) throws -> Lazy {
let reader = try CSVReader(input: data, configuration: self._configuration.readerConfiguration)
let source = ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)
return Lazy(source: source)
}
/// Returns a sequence for decoding row-by-row from a CSV file (given as a `String`).
/// - parameter string: A Swift string representing a CSV file.
/// - throws: `CSVError<CSVReader>` exclusively.
public func lazy(from string: String) throws -> Lazy {
let reader = try CSVReader(input: string, configuration: self._configuration.readerConfiguration)
let source = ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)
return Lazy(source: source)
}
/// Returns a sequence for decoding row-by-row from a CSV file (being pointed by `url`).
/// - parameter url: The URL pointing to the file to decode.
/// - throws: `CSVError<CSVReader>` exclusively.
public func lazy(from url: URL) throws -> Lazy {
let reader = try CSVReader(input: url, configuration: self._configuration.readerConfiguration)
let source = ShadowDecoder.Source(reader: reader, configuration: self._configuration, userInfo: self.userInfo)
return Lazy(source: source)
}
}
#if canImport(Combine)
import Combine
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension CSVDecoder: TopLevelDecoder {
public typealias Input = Data
}
#endif