use std::future::Future;
use crate::MaybeSend;
pub fn spawn<F>(future: F)
where
F: Future<Output = ()> + MaybeSend + 'static,
{
#[cfg(not(target_arch = "wasm32"))]
tokio::spawn(future);
#[cfg(target_arch = "wasm32")]
wasm_bindgen_futures::spawn_local(future);
}
#[cfg(test)]
mod test {
use std::time::Duration;
use tokio::sync::{mpsc, oneshot};
use crate::timeout;
use super::*;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
async fn spawned_task_runs() {
let (tx, rx) = oneshot::channel();
spawn(async move {
tx.send(42).unwrap();
});
let received = timeout(Duration::from_secs(5), rx).await
.expect("the spawned task should have sent its value")
.expect("the sender should not have been dropped");
assert_eq!(42, received);
}
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
async fn spawned_task_continues_after_awaiting() {
let (tx, mut rx) = mpsc::channel(2);
spawn(async move {
tx.send(1).await.unwrap();
crate::sleep(Duration::from_millis(10)).await;
tx.send(2).await.unwrap();
});
assert_eq!(Some(1), rx.recv().await);
assert_eq!(Some(2), rx.recv().await);
}
#[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
async fn all_spawned_tasks_run() {
let (tx, mut rx) = mpsc::channel(3);
for i in 0..3 {
let tx = tx.clone();
spawn(async move {
tx.send(i).await.unwrap();
});
}
drop(tx);
let mut received = Vec::new();
while let Some(i) = rx.recv().await {
received.push(i);
}
received.sort();
assert_eq!(vec![0, 1, 2], received);
}
}