// Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::helpers::{leak, spawn_timeboxed}; use std::future::{Future, IntoFuture}; use std::time::Duration; use tokio::task::JoinHandle; use tokio::time::error::Elapsed; // a helper trait for use in tests to easily convert `T` into `&'static mut T` pub trait Leak { fn leak(self) -> &'static mut Self; } impl Leak for T { fn leak(self) -> &'static mut T { leak(self) } } // those are internal testing traits so we're not concerned about auto traits #[allow(async_fn_in_trait)] pub trait Timeboxed: IntoFuture + Sized { async fn timeboxed(self) -> Result { self.execute_with_deadline(Duration::from_millis(200)).await } async fn execute_with_deadline(self, timeout: Duration) -> Result { tokio::time::timeout(timeout, self).await } } impl Timeboxed for T where T: IntoFuture + Sized {} pub trait ElapsedExt { fn has_elapsed(&self) -> bool; } impl ElapsedExt for Result { fn has_elapsed(&self) -> bool { self.is_err() } } // those are internal testing traits so we're not concerned about auto traits #[allow(async_fn_in_trait)] pub trait Spawnable: Future + Sized + Send + 'static { fn spawn(self) -> JoinHandle where ::Output: Send + 'static, { tokio::spawn(self) } } impl Spawnable for T where T: Future + Sized + Send + 'static {} pub trait TimeboxedSpawnable: Timeboxed + Spawnable { fn spawn_timeboxed(self) -> JoinHandle::Output, Elapsed>> where ::Output: Send, { spawn_timeboxed(self) } } impl TimeboxedSpawnable for T where T: Spawnable + Future + Send {}