//! This module provides utilities for working with JavaScript types //! which do not implement `Send`, in contexts where `Send` is required. //! Workers is guaranteed to be single-threaded, so it is safe to //! wrap any type with `Send` and `Sync` traits. use futures_util::future::Future; use pin_project::pin_project; use std::fmt::Debug; use std::fmt::Display; use std::pin::Pin; use std::task::Context; use std::task::Poll; #[derive(Debug)] #[pin_project] /// Wrap any future to make it `Send`. /// /// ```rust /// let fut = SendFuture::new(JsFuture::from(promise)); /// fut.await /// ``` pub struct SendFuture { #[pin] inner: F, } impl SendFuture { pub fn new(inner: F) -> Self { Self { inner } } } unsafe impl Send for SendFuture {} unsafe impl Sync for SendFuture {} impl Future for SendFuture { type Output = F::Output; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); this.inner.poll(cx) } } /// Trait for SendFuture. Implemented for any type that implements Future. /// /// ```rust /// let fut = JsFuture::from(promise).into_send(); /// fut.await /// ``` pub trait IntoSendFuture { type Output; fn into_send(self) -> SendFuture where Self: Sized; } impl IntoSendFuture for F where F: Future, { type Output = T; fn into_send(self) -> SendFuture { SendFuture::new(self) } } /// Wrap any type to make it `Send`. /// /// ```rust /// // js_sys::Promise is !Send /// let send_promise = SendWrapper::new(promise); /// ``` pub struct SendWrapper(pub T); unsafe impl Send for SendWrapper {} unsafe impl Sync for SendWrapper {} impl SendWrapper { pub fn new(inner: T) -> Self { Self(inner) } } impl std::ops::Deref for SendWrapper { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl std::ops::DerefMut for SendWrapper { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl Debug for SendWrapper { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "SendWrapper({:?})", self.0) } } impl Clone for SendWrapper { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Default for SendWrapper { fn default() -> Self { Self(T::default()) } } impl Display for SendWrapper { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "SendWrapper({})", self.0) } }