-
-
Save jeksys/6d6da13e1405d66501b52e0abaf9b66b to your computer and use it in GitHub Desktop.
This file contains 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
import PlaygroundSupport | |
import Foundation | |
struct Resource<A> { | |
var request: URLRequest | |
var parse: (Data) throws -> A | |
} | |
protocol Loadable { | |
static var request: URLRequest { get } | |
init(parsing data: Data) throws | |
} | |
struct Country: Codable { | |
var alpha2Code: String | |
var name: String | |
var population: Int | |
} | |
extension Resource where A: Decodable { | |
init(get url: URL) { | |
self.init(request: URLRequest(url: url)) { data in | |
try JSONDecoder().decode(A.self, from: data) | |
} | |
} | |
} | |
extension Loadable where Self: Decodable { | |
init(parsing data: Data) throws { | |
self = try JSONDecoder().decode(Self.self, from: data) | |
} | |
} | |
let countries = Resource<[Country]>(get: URL(string: "https://restcountries.eu/rest/v2/all")!) | |
extension Array: Loadable where Element == Country { | |
static var request: URLRequest { | |
return URLRequest(url: URL(string: "https://restcountries.eu/rest/v2/all")!) | |
} | |
} | |
extension URLSession { | |
func load<A>(_ r: Resource<A>, callback: @escaping (Result<A, Error>) -> ()) { | |
dataTask(with: r.request) { data, response, err in | |
callback(Result { | |
if let e = err { throw e } | |
guard let d = data else { fatalError() } | |
return try r.parse(d) | |
}) | |
}.resume() | |
} | |
func load<A: Loadable>(_ type: A.Type, callback: @escaping (Result<A, Error>) -> ()) { | |
dataTask(with: type.request) { data, response, err in | |
callback(Result { | |
if let e = err { throw e } | |
guard let d = data else { fatalError() } | |
return try type.init(parsing: d) | |
}) | |
}.resume() | |
} | |
} | |
PlaygroundPage.current.needsIndefiniteExecution = true | |
URLSession.shared.load(countries) { print($0) } | |
URLSession.shared.load([Country].self) { print($0) } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment