-
Notifications
You must be signed in to change notification settings - Fork 384
/
Copy pathapi.rs
71 lines (60 loc) · 2.51 KB
/
api.rs
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
use mullvad_api::{
rest::{self, MullvadRestHandle},
ApiProxy,
};
use talpid_future::retry::retry_future;
use super::{
cancellation::{RequestCancelHandle, SwiftCancelHandle},
completion::{CompletionCookie, SwiftCompletionHandler},
response::SwiftMullvadApiResponse,
retry_strategy::{RetryStrategy, SwiftRetryStrategy},
SwiftApiContext,
};
/// # Safety
///
/// `api_context` must be pointing to a valid instance of `SwiftApiContext`. A `SwiftApiContext` is created
/// by calling `mullvad_api_init_new`.
///
/// `completion_cookie` must be pointing to a valid instance of `CompletionCookie`. `CompletionCookie` is
/// safe because the pointer in `MullvadApiCompletion` is valid for the lifetime of the process where this
/// type is intended to be used.
///
/// This function is not safe to call multiple times with the same `CompletionCookie`.
#[no_mangle]
pub unsafe extern "C" fn mullvad_api_get_addresses(
api_context: SwiftApiContext,
completion_cookie: *mut libc::c_void,
retry_strategy: SwiftRetryStrategy,
) -> SwiftCancelHandle {
let completion_handler = SwiftCompletionHandler::new(CompletionCookie(completion_cookie));
let Ok(tokio_handle) = crate::mullvad_ios_runtime() else {
completion_handler.finish(SwiftMullvadApiResponse::no_tokio_runtime());
return SwiftCancelHandle::empty();
};
let api_context = api_context.into_rust_context();
let retry_strategy = unsafe { retry_strategy.into_rust() };
let completion = completion_handler.clone();
let task = tokio_handle.clone().spawn(async move {
match mullvad_api_get_addresses_inner(api_context.rest_handle(), retry_strategy).await {
Ok(response) => completion.finish(response),
Err(err) => {
log::error!("{err:?}");
completion.finish(SwiftMullvadApiResponse::rest_error(err));
}
}
});
RequestCancelHandle::new(task, completion_handler.clone()).into_swift()
}
async fn mullvad_api_get_addresses_inner(
rest_client: MullvadRestHandle,
retry_strategy: RetryStrategy,
) -> Result<SwiftMullvadApiResponse, rest::Error> {
let api = ApiProxy::new(rest_client);
let future_factory = || api.get_api_addrs_response();
let should_retry = |result: &Result<_, rest::Error>| match result {
Err(err) => err.is_network_error(),
Ok(_) => false,
};
let response = retry_future(future_factory, should_retry, retry_strategy.delays()).await?;
SwiftMullvadApiResponse::with_body(response).await
}