nym_test_utils/
traits.rs

1// Copyright 2025 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::helpers::{leak, spawn_timeboxed};
5use std::future::{Future, IntoFuture};
6use std::time::Duration;
7use tokio::task::JoinHandle;
8use tokio::time::error::Elapsed;
9
10// a helper trait for use in tests to easily convert `T` into `&'static mut T`
11pub trait Leak {
12    fn leak(self) -> &'static mut Self;
13}
14
15impl<T> Leak for T {
16    fn leak(self) -> &'static mut T {
17        leak(self)
18    }
19}
20
21// those are internal testing traits so we're not concerned about auto traits
22#[allow(async_fn_in_trait)]
23pub trait Timeboxed: IntoFuture + Sized {
24    async fn timeboxed(self) -> Result<Self::Output, Elapsed> {
25        self.execute_with_deadline(Duration::from_millis(200)).await
26    }
27
28    async fn execute_with_deadline(self, timeout: Duration) -> Result<Self::Output, Elapsed> {
29        tokio::time::timeout(timeout, self).await
30    }
31}
32
33impl<T> Timeboxed for T where T: IntoFuture + Sized {}
34
35pub trait ElapsedExt {
36    fn has_elapsed(&self) -> bool;
37}
38
39impl<T> ElapsedExt for Result<T, Elapsed> {
40    fn has_elapsed(&self) -> bool {
41        self.is_err()
42    }
43}
44
45// those are internal testing traits so we're not concerned about auto traits
46#[allow(async_fn_in_trait)]
47pub trait Spawnable: Future + Sized + Send + 'static {
48    fn spawn(self) -> JoinHandle<Self::Output>
49    where
50        <Self as Future>::Output: Send + 'static,
51    {
52        tokio::spawn(self)
53    }
54}
55
56impl<T> Spawnable for T where T: Future + Sized + Send + 'static {}
57
58pub trait TimeboxedSpawnable: Timeboxed + Spawnable {
59    fn spawn_timeboxed(self) -> JoinHandle<Result<<Self as Future>::Output, Elapsed>>
60    where
61        <Self as Future>::Output: Send,
62    {
63        spawn_timeboxed(self)
64    }
65}
66
67impl<T> TimeboxedSpawnable for T where T: Spawnable + Future + Send {}