Created
August 28, 2017 21:25
-
-
Save vhart/3457fc681f2dd6a3dc4365f8d8c45f28 to your computer and use it in GitHub Desktop.
Full Type Erased Scenario
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public enum Result<T, E: Error> { | |
case success(T) | |
case failure(E) | |
} | |
public enum NetworkError: Error { | |
case invalidJson | |
case badRequest | |
case timeout | |
} | |
public protocol JsonDeserializer { | |
associatedtype Response | |
func parse(json: [String: Any]) -> Response | |
} | |
public protocol NetworkSession { | |
associatedtype Payload | |
func get(url: URL, | |
parameters: [String: String], | |
onComplete: (Result<Payload, NetworkError>) -> Void) | |
} | |
private class BaseDeserializer<T>: JsonDeserializer { | |
init() { | |
guard type(of: self) != BaseDeserializer.self | |
else { fatalError("do not initialize this abstract class directly") } | |
} | |
func parse(json: [String : Any]) -> T { | |
fatalError("Abstract class. Subclass must override") | |
} | |
} | |
private class DeserializerBox<D: JsonDeserializer>: BaseDeserializer<D.Response> { | |
private let deserializer: D | |
init(concreteDeserializer: D) { | |
self.deserializer = concreteDeserializer | |
} | |
override func parse(json: [String : Any]) -> D.Response { | |
return deserializer.parse(json: json) | |
} | |
} | |
public class AnyJsonDeserializer<T>: JsonDeserializer { | |
private let deserializerBox: BaseDeserializer<T> | |
public init<Concrete: JsonDeserializer>(_ deserializer: Concrete) | |
where Concrete.Response == T { | |
let box = DeserializerBox(concreteDeserializer: deserializer) | |
self.deserializerBox = box | |
} | |
public func parse(json: [String : Any]) -> T { | |
return deserializerBox.parse(json: json) | |
} | |
} | |
public class Session<P>: NetworkSession { | |
public typealias Payload = P | |
let deserializer: AnyJsonDeserializer<Payload> | |
public init(deserializer: AnyJsonDeserializer<Payload>) { | |
self.deserializer = deserializer | |
} | |
public func get(url: URL, | |
parameters: [String: String], | |
onComplete: (Result<Payload, NetworkError>) -> Void) {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment