tightbeam/utils/marker.rs
1//! Target-conditional `Send`/`Sync` markers for async traits.
2//!
3//! Native targets run on multi-threaded executors and MUST stay `Send`/`Sync`.
4//! `wasm32` is single-threaded and its JS-backed futures and handles are
5//! `!Send`, so these markers collapse to no-op bounds there.
6
7#[cfg(not(feature = "std"))]
8use alloc::boxed::Box;
9
10use core::future::Future;
11use core::pin::Pin;
12
13/// Requires `Send` on every target except `wasm32`, where it is a no-op.
14#[cfg(not(target_arch = "wasm32"))]
15pub trait MaybeSend: Send {}
16#[cfg(not(target_arch = "wasm32"))]
17impl<T: Send> MaybeSend for T {}
18
19/// Requires `Send` on every target except `wasm32`, where it is a no-op.
20#[cfg(target_arch = "wasm32")]
21pub trait MaybeSend {}
22#[cfg(target_arch = "wasm32")]
23impl<T> MaybeSend for T {}
24
25/// Requires `Sync` on every target except `wasm32`, where it is a no-op.
26#[cfg(not(target_arch = "wasm32"))]
27pub trait MaybeSync: Sync {}
28#[cfg(not(target_arch = "wasm32"))]
29impl<T: Sync> MaybeSync for T {}
30
31/// Requires `Sync` on every target except `wasm32`, where it is a no-op.
32#[cfg(target_arch = "wasm32")]
33pub trait MaybeSync {}
34#[cfg(target_arch = "wasm32")]
35impl<T> MaybeSync for T {}
36
37/// Boxed future whose `Send` requirement is relaxed on `wasm32`.
38///
39/// A `dyn` trait object cannot carry the non-auto [`MaybeSend`] bound, so the
40/// `Send` bound is target-gated directly here while keeping the owning trait
41/// dyn-compatible.
42#[cfg(not(target_arch = "wasm32"))]
43pub type MaybeSendFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
44
45/// Boxed future whose `Send` requirement is relaxed on `wasm32`.
46#[cfg(target_arch = "wasm32")]
47pub type MaybeSendFuture<'a, T> = Pin<Box<dyn Future<Output = T> + 'a>>;