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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! Platform-adaptive marker traits for cross-platform compatibility.
//!
//! These traits enable unified handler definitions that work on both native and WASM targets.
//! On native targets, the traits require `Send`/`Sync` bounds for multi-threaded executors.
//! On WASM targets, the traits have no bounds since WASM is single-threaded and `JsValue` is `!Send`.
//!
//! # Background
//!
//! The fundamental challenge for unified native/WASM code is that [`wasm_bindgen::JsValue`]
//! is `!Send` by design due to JavaScript's slab-based object management. This has
//! "huge trickle-down effects" on downstream crates.
//!
//! The solution is conditional compilation with marker traits that adapt to the target.
//!
//! # Example
//!
//! ```rust,ignore
//! use turbomcp_core::{MaybeSend, MaybeSync};
//!
//! // This trait works on both native (with Send) and WASM (without Send)
//! trait MyHandler: MaybeSend + MaybeSync {
//! fn handle(&self) -> impl Future<Output = ()> + MaybeSend;
//! }
//! ```
//!
//! # Platform Behavior
//!
//! - **Native (`x86_64`, `aarch64`, etc.)**: `MaybeSend` requires `Send`, `MaybeSync` requires `Sync`
//! - **WASM (`wasm32`)**: Both traits are blanket-implemented for all types (no bounds)
/// Marker trait that requires `Send` on native targets, nothing on WASM.
///
/// This enables unified trait definitions that work on both platforms:
/// - On native: futures must be `Send` for multi-threaded executors like tokio
/// - On WASM: no `Send` bound needed since WASM is single-threaded
///
/// # Example
///
/// ```rust,ignore
/// use turbomcp_core::MaybeSend;
/// use std::future::Future;
///
/// trait MyAsyncTrait {
/// fn do_work(&self) -> impl Future<Output = ()> + MaybeSend;
/// }
/// ```
/// Marker trait with no bounds on WASM (single-threaded).
///
/// On WASM targets, `MaybeSend` is blanket-implemented for all types since
/// WASM is single-threaded and doesn't require `Send` bounds.
/// Marker trait that requires `Sync` on native targets, nothing on WASM.
///
/// This enables unified trait definitions that work on both platforms:
/// - On native: handlers must be `Sync` for shared access across threads
/// - On WASM: no `Sync` bound needed since WASM is single-threaded
///
/// # Example
///
/// ```rust,ignore
/// use turbomcp_core::{MaybeSend, MaybeSync};
///
/// trait MyHandler: Clone + MaybeSend + MaybeSync + 'static {
/// fn handle(&self);
/// }
/// ```
/// Marker trait with no bounds on WASM (single-threaded).
///
/// On WASM targets, `MaybeSync` is blanket-implemented for all types since
/// WASM is single-threaded and doesn't require `Sync` bounds.