Skip to content

Instantly share code, notes, and snippets.

@ytyubox
Created November 30, 2021 00:17
Show Gist options
  • Save ytyubox/c11dfc47eb2b068da454046a3fe1b656 to your computer and use it in GitHub Desktop.
Save ytyubox/c11dfc47eb2b068da454046a3fe1b656 to your computer and use it in GitHub Desktop.
import Foundation
import XCTest
final class DecodeTests: XCTestCase {
func testMeta1() throws {
let rawJson =
"""
{
"a1": {
"key1": "value1",
"key2": "value2"
},
"b1": {
"key1": "value3",
"key2": "value4"
},
"a2": {
"key3": false,
"key4": 123
}
}
"""
let json = try XCTUnwrap(rawJson.data(using: .utf8))
let decoder = JSONDecoder()
let model = try decoder.decode([String: Either<Meta1, Meta2>].self,
from: json)
XCTAssertEqual(model, [
"a1" : .either(Meta1(key1: "value1", key2: "value2")),
"b1" : .either(Meta1(key1: "value3", key2: "value4")),
"a2" : .or(Meta2(key3: false, key4: 123))
])
}
}
// MARK: - Meta Data
struct Meta1:Decodable, Equatable {
let key1: String
let key2: String
}
struct Meta2: Decodable, Equatable {
let key3: Bool
let key4: Double
}
enum Either<T,U> {
case either(T), or(U)
}
extension Either: Decodable where T: Decodable, U: Decodable {
init(from decoder: Decoder) throws {
do {
let t = try T.init(from: decoder)
self = .either(t)
} catch let tError {
do {
self = try .or(U.init(from: decoder))
} catch let uError {
throw EitherError(tError: tError, uError: uError)
}
}
}
struct EitherError: LocalizedError, CustomStringConvertible {
var tError: Error
var uError: Error
var errorDescription: String? {
tError.localizedDescription
}
var description: String {
"""
Both T, U Decode fail
tError:
\(tError)
uError:
\(uError)
"""
}
}
}
extension Either: Equatable where T: Equatable, U: Equatable {}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment