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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
//
// MullvadAccountProxy.swift
// MullvadVPN
//
// Created by Jon Petersson on 2025-03-31.
// Copyright © 2025 Mullvad VPN AB. All rights reserved.
//
import MullvadRustRuntime
import MullvadTypes
import Operations
import WireGuardKitTypes
public protocol RESTAccountHandling: Sendable {
func createAccount(
retryStrategy: REST.RetryStrategy,
completion: @escaping @Sendable ProxyCompletionHandler<NewAccountData>
) -> Cancellable
func getAccountData(
accountNumber: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping @Sendable ProxyCompletionHandler<Account>
) -> Cancellable
func deleteAccount(
accountNumber: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping ProxyCompletionHandler<Void>
) -> Cancellable
}
extension REST {
public final class MullvadAccountProxy: RESTAccountHandling, @unchecked Sendable {
let transportProvider: APITransportProviderProtocol
let dispatchQueue: DispatchQueue
let operationQueue = AsyncOperationQueue()
let responseDecoder: JSONDecoder
public init(
transportProvider: APITransportProviderProtocol,
dispatchQueue: DispatchQueue,
responseDecoder: JSONDecoder
) {
self.transportProvider = transportProvider
self.dispatchQueue = dispatchQueue
self.responseDecoder = responseDecoder
}
public func createAccount(
retryStrategy: REST.RetryStrategy,
completion: @escaping ProxyCompletionHandler<NewAccountData>
) -> Cancellable {
let responseHandler = rustResponseHandler(
decoding: NewAccountData.self,
with: responseDecoder
)
return createNetworkOperation(
request: .createAccount(retryStrategy),
responseHandler: responseHandler,
completionHandler: completion
)
}
public func getAccountData(
accountNumber: String,
retryStrategy: REST.RetryStrategy,
completion: @escaping ProxyCompletionHandler<Account>
) -> Cancellable {
let responseHandler = rustResponseHandler(
decoding: Account.self,
with: responseDecoder
)
return createNetworkOperation(
request: .getAccount(retryStrategy, accountNumber: accountNumber),
responseHandler: responseHandler,
completionHandler: completion
)
}
public func deleteAccount(
accountNumber: String,
retryStrategy: RetryStrategy,
completion: @escaping ProxyCompletionHandler<Void>
) -> Cancellable {
let request = APIRequest.deleteAccount(retryStrategy, accountNumber: accountNumber)
let networkOperation = MullvadApiNetworkOperation(
name: request.name,
dispatchQueue: dispatchQueue,
request: request,
transportProvider: transportProvider,
responseDecoder: responseDecoder,
responseHandler: rustEmptyResponseHandler(),
completionHandler: completion
)
operationQueue.addOperation(networkOperation)
return networkOperation
}
private func createNetworkOperation<Success: Decodable>(
request: APIRequest,
responseHandler: RustResponseHandler<Success>,
completionHandler: @escaping @Sendable ProxyCompletionHandler<Success>
) -> MullvadApiNetworkOperation<Success> {
let networkOperation = MullvadApiNetworkOperation(
name: request.name,
dispatchQueue: dispatchQueue,
request: request,
transportProvider: transportProvider,
responseDecoder: responseDecoder,
responseHandler: responseHandler,
completionHandler: completionHandler
)
operationQueue.addOperation(networkOperation)
return networkOperation
}
}
}
|