Skip to main content

libdd_capabilities/
maybe_send.rs

1// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/
2// SPDX-License-Identifier: Apache-2.0
3
4//! Conditional `Send` bound for cross-platform compatibility.
5//!
6//! On native targets, `MaybeSend` is equivalent to `Send`.
7//! On wasm32, `MaybeSend` is auto-implemented for all types.
8//!
9//! This allows traits to require `Send` on native (for multi-threaded runtimes)
10//! while remaining compatible with wasm's single-threaded execution model.
11//!
12//! # Why This Exists
13//!
14//! JavaScript interop types (like `JsFuture`, `JsValue`) are **not `Send`**
15//! because wasm is single-threaded. But on native, tokio's multi-threaded
16//! runtime requires `Send` futures. `MaybeSend` bridges this gap:
17//!
18//! ```rust,ignore
19//! // Instead of:
20//! fn request() -> impl Future<Output = Response> + Send;  // Won't compile on wasm!
21//!
22//! // Use:
23//! fn request() -> impl Future<Output = Response> + MaybeSend;  // Works everywhere!
24//! ```
25//!
26//! # Critical Rule
27//!
28//! **Never use `+ Send` directly in trait bounds for async functions in
29//! wasm-compatible code.** Always use `+ MaybeSend` instead.
30
31/// A trait that is `Send` on native targets, but auto-implemented on wasm.
32///
33/// Use this instead of `Send` in all capability trait bounds.
34#[cfg(not(target_arch = "wasm32"))]
35pub trait MaybeSend: Send {}
36
37#[cfg(not(target_arch = "wasm32"))]
38impl<T: Send> MaybeSend for T {}
39
40/// On wasm, `MaybeSend` is implemented for all types (no `Send` requirement).
41#[cfg(target_arch = "wasm32")]
42pub trait MaybeSend {}
43
44#[cfg(target_arch = "wasm32")]
45impl<T> MaybeSend for T {}