Newer
Older
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
import Foundation
import SwiftCSV
import XCTestDynamicOverlay
public struct ProcessBannedList {
public enum ElementError: Swift.Error {
case missingUserId
case invalidUserId(String)
}
public enum Error: Swift.Error {
case invalidData
case csv(Swift.Error)
}
public typealias ForEach = (Result<Data, ElementError>) -> Void
public typealias Completion = (Result<Void, Error>) -> Void
public var run: (Data, ForEach, Completion) -> Void
public func callAsFunction(
data: Data,
forEach: ForEach,
completion: Completion
) {
run(data, forEach, completion)
}
}
extension ProcessBannedList {
public static let live = ProcessBannedList { data, forEach, completion in
guard let csvString = String(data: data, encoding: .utf8) else {
completion(.failure(.invalidData))
return
}
let csv: EnumeratedCSV
do {
csv = try EnumeratedCSV(string: csvString)
}
catch {
completion(.failure(.csv(error)))
return
}
csv.rows.forEach { row in
guard let userIdString = row.first else {
forEach(.failure(.missingUserId))
return
}
guard let userId = Data(base64Encoded: userIdString) else {
forEach(.failure(.invalidUserId(userIdString)))
return
}
forEach(.success(userId))
}
completion(.success(()))
}
}
extension ProcessBannedList {
public static let unimplemented = ProcessBannedList { _, _, _ in
let run: () -> Void = XCTUnimplemented("\(Self.self)")
run()
}
}