use std::future::Future;
use std::pin::Pin;
use std::time::Duration;
#[cfg(not(target_arch = "wasm32"))]
pub trait Spawn: Send + Sync + 'static {
fn spawn(&self, fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>);
}
#[cfg(target_arch = "wasm32")]
pub trait Spawn: 'static {
fn spawn(&self, fut: Pin<Box<dyn Future<Output = ()> + 'static>>);
}
#[cfg(not(target_arch = "wasm32"))]
pub trait Timer: Send + Sync + 'static {
fn sleep(&self, dur: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>>;
}
#[cfg(target_arch = "wasm32")]
pub trait Timer: 'static {
fn sleep(&self, dur: Duration) -> Pin<Box<dyn Future<Output = ()> + 'static>>;
}
#[derive(Debug, thiserror::Error)]
pub enum WsRtError {
#[error("connect: {0}")]
Connect(String),
#[error("send: {0}")]
Send(String),
#[error("recv: {0}")]
Recv(String),
#[error("closed by peer")]
Closed,
#[error("timeout")]
Timeout,
}
#[derive(Debug, Clone, PartialEq)]
pub enum WsFrame {
Text(String),
Binary(Vec<u8>),
Ping(Vec<u8>),
Pong(Vec<u8>),
Close,
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait::async_trait]
pub trait WsConnector: Send + Sync + 'static {
async fn connect(&self, url: &str, timeout: Duration) -> Result<Box<dyn WsConn>, WsRtError>;
}
#[cfg(target_arch = "wasm32")]
#[async_trait::async_trait(?Send)]
pub trait WsConnector: 'static {
async fn connect(&self, url: &str, timeout: Duration) -> Result<Box<dyn WsConn>, WsRtError>;
}
#[cfg(not(target_arch = "wasm32"))]
#[async_trait::async_trait]
pub trait WsConn: Send + 'static {
async fn send(&mut self, frame: WsFrame) -> Result<(), WsRtError>;
async fn next_frame(&mut self) -> Option<Result<WsFrame, WsRtError>>;
async fn close(&mut self) -> Result<(), WsRtError>;
}
#[cfg(target_arch = "wasm32")]
#[async_trait::async_trait(?Send)]
pub trait WsConn: 'static {
async fn send(&mut self, frame: WsFrame) -> Result<(), WsRtError>;
async fn next_frame(&mut self) -> Option<Result<WsFrame, WsRtError>>;
async fn close(&mut self) -> Result<(), WsRtError>;
}
#[cfg(not(target_arch = "wasm32"))]
pub mod native;
#[cfg(target_arch = "wasm32")]
pub mod wasm;
pub mod clock;
pub struct Runtime(
#[cfg(not(target_arch = "wasm32"))]
pub(crate) native::TokioRuntime,
#[cfg(target_arch = "wasm32")]
pub(crate) wasm::WasmRuntime,
);
impl Runtime {
#[cfg(not(target_arch = "wasm32"))]
pub fn spawn_send(&self, fut: Pin<Box<dyn Future<Output = ()> + Send + 'static>>) {
self.0.spawn(fut);
}
#[cfg(target_arch = "wasm32")]
pub fn spawn_local(&self, fut: Pin<Box<dyn Future<Output = ()> + 'static>>) {
self.0.spawn(fut);
}
#[cfg(not(target_arch = "wasm32"))]
pub fn sleep(&self, dur: Duration) -> Pin<Box<dyn Future<Output = ()> + Send + 'static>> {
self.0.sleep(dur)
}
#[cfg(target_arch = "wasm32")]
pub fn sleep(&self, dur: Duration) -> Pin<Box<dyn Future<Output = ()> + 'static>> {
self.0.sleep(dur)
}
pub async fn connect_ws(
&self,
url: &str,
timeout: Duration,
) -> Result<Box<dyn WsConn>, WsRtError> {
self.0.connect(url, timeout).await
}
}
pub fn default_runtime() -> Runtime {
#[cfg(not(target_arch = "wasm32"))]
return Runtime(native::TokioRuntime);
#[cfg(target_arch = "wasm32")]
return Runtime(wasm::WasmRuntime);
}