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
|
//
// RESTRequestHandler.swift
// MullvadVPN
//
// Created by pronebird on 20/04/2022.
// Copyright © 2022 Mullvad VPN AB. All rights reserved.
//
import Foundation
protocol RESTRequestHandler {
typealias AuthorizationCompletion = (OperationCompletion<REST.Authorization, REST.Error>) -> Void
func createURLRequest(endpoint: AnyIPEndpoint, authorization: REST.Authorization?) -> Result<URLRequest, REST.Error>
func requestAuthorization(completion: @escaping AuthorizationCompletion) -> REST.AuthorizationResult
}
extension REST {
enum AuthorizationResult {
/// There is no requirement for authorizing this request.
case noRequirement
/// Authorization request is initiated.
/// Associated value contains a handle that can be used to cancel
/// the request.
case pending(Cancellable)
}
final class AnyRequestHandler: RESTRequestHandler {
private let _createURLRequest: (AnyIPEndpoint, REST.Authorization?) -> Result<URLRequest, REST.Error>
private let _requestAuthorization: ((@escaping AuthorizationCompletion) -> AuthorizationResult)?
init(createURLRequest: @escaping (AnyIPEndpoint) -> Result<URLRequest, REST.Error>) {
_createURLRequest = { endpoint, authorization in
createURLRequest(endpoint)
}
_requestAuthorization = nil
}
init(
createURLRequest: @escaping (AnyIPEndpoint, REST.Authorization) -> Result<URLRequest, REST.Error>,
requestAuthorization: @escaping (@escaping AuthorizationCompletion) -> Cancellable
) {
_createURLRequest = { endpoint, authorization in
return createURLRequest(endpoint, authorization!)
}
_requestAuthorization = { completion in
return .pending(requestAuthorization(completion))
}
}
func createURLRequest(
endpoint: AnyIPEndpoint,
authorization: REST.Authorization?
) -> Result<URLRequest, REST.Error> {
return _createURLRequest(endpoint, authorization)
}
func requestAuthorization(
completion: @escaping (OperationCompletion<REST.Authorization, REST.Error>) -> Void
) -> REST.AuthorizationResult {
return _requestAuthorization?(completion) ?? .noRequirement
}
}
}
|