#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct WasmSend<T>(pub T);
#[cfg(target_family = "wasm")]
unsafe impl<T> Send for WasmSend<T> {}
impl<T> WasmSend<T> {
pub const fn new(value: T) -> Self {
Self(value)
}
pub fn into_inner(self) -> T {
self.0
}
pub const fn inner(&self) -> &T {
&self.0
}
#[allow(
clippy::missing_const_for_fn,
reason = "&mut self in const fn is unstable"
)]
pub fn inner_mut(&mut self) -> &mut T {
&mut self.0
}
}
impl<T> std::ops::Deref for WasmSend<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> std::ops::DerefMut for WasmSend<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
#[cfg(target_family = "wasm")]
pub fn force_send<F: std::future::Future>(
future: F,
) -> impl std::future::Future<Output = F::Output> + Send {
ForceSend(future)
}
#[cfg(not(target_family = "wasm"))]
pub fn force_send<F: std::future::Future + Send>(
future: F,
) -> impl std::future::Future<Output = F::Output> + Send {
future
}
#[cfg(target_family = "wasm")]
struct ForceSend<F>(F);
#[cfg(target_family = "wasm")]
unsafe impl<F> Send for ForceSend<F> {}
#[cfg(target_family = "wasm")]
impl<F: std::future::Future> std::future::Future for ForceSend<F> {
type Output = F::Output;
fn poll(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Self::Output> {
unsafe { self.map_unchecked_mut(|s| &mut s.0).poll(cx) }
}
}
#[cfg(target_family = "wasm")]
pub fn force_send_stream<S: futures::Stream>(
stream: S,
) -> impl futures::Stream<Item = S::Item> + Send {
ForceSendStream(stream)
}
#[cfg(not(target_family = "wasm"))]
pub fn force_send_stream<S: futures::Stream + Send>(
stream: S,
) -> impl futures::Stream<Item = S::Item> + Send {
stream
}
#[cfg(target_family = "wasm")]
struct ForceSendStream<S>(S);
#[cfg(target_family = "wasm")]
unsafe impl<S> Send for ForceSendStream<S> {}
#[cfg(target_family = "wasm")]
impl<S: futures::Stream> futures::Stream for ForceSendStream<S> {
type Item = S::Item;
fn poll_next(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> std::task::Poll<Option<Self::Item>> {
unsafe { self.map_unchecked_mut(|s| &mut s.0).poll_next(cx) }
}
}