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
// Copyright (c) 2022-2023 Yuki Kishimoto
// Distributed under the MIT software license

//! Time module

use core::future::Future;
use core::time::Duration;

#[cfg(target_arch = "wasm32")]
use futures_util::future::{AbortHandle, Abortable};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_futures::spawn_local;

/// Timeout
pub async fn timeout<F>(timeout: Option<Duration>, future: F) -> Option<F::Output>
where
    F: Future,
{
    #[cfg(not(target_arch = "wasm32"))]
    if let Some(timeout) = timeout {
        tokio::time::timeout(timeout, future).await.ok()
    } else {
        Some(future.await)
    }

    #[cfg(target_arch = "wasm32")]
    {
        if let Some(timeout) = timeout {
            let (abort_handle, abort_registration) = AbortHandle::new_pair();
            let future = Abortable::new(future, abort_registration);
            spawn_local(async move {
                gloo_timers::callback::Timeout::new(timeout.as_millis() as u32, move || {
                    abort_handle.abort();
                })
                .forget();
            });
            future.await.ok()
        } else {
            Some(future.await)
        }
    }
}