1use std::future::Future;
2
3use crate::MaybeSend;
4
5pub fn spawn<F>(future: F)
10where
11 F: Future<Output = ()> + MaybeSend + 'static,
12{
13 #[cfg(not(target_arch = "wasm32"))]
14 tokio::spawn(future);
15
16 #[cfg(target_arch = "wasm32")]
17 wasm_bindgen_futures::spawn_local(future);
18}
19
20#[cfg(test)]
21mod test {
22 use std::time::Duration;
23
24 use tokio::sync::{mpsc, oneshot};
25
26 use crate::timeout;
27
28 use super::*;
29
30 #[cfg(target_arch = "wasm32")]
31 use wasm_bindgen_test::wasm_bindgen_test;
32 #[cfg(target_arch = "wasm32")]
33 wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
34
35 #[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
37 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
38 async fn spawned_task_runs() {
39 let (tx, rx) = oneshot::channel();
40 spawn(async move {
41 tx.send(42).unwrap();
42 });
43
44 let received = timeout(Duration::from_secs(5), rx).await
45 .expect("the spawned task should have sent its value")
46 .expect("the sender should not have been dropped");
47 assert_eq!(42, received);
48 }
49
50 #[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
52 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
53 async fn spawned_task_continues_after_awaiting() {
54 let (tx, mut rx) = mpsc::channel(2);
55 spawn(async move {
56 tx.send(1).await.unwrap();
57 crate::sleep(Duration::from_millis(10)).await;
58 tx.send(2).await.unwrap();
59 });
60
61 assert_eq!(Some(1), rx.recv().await);
62 assert_eq!(Some(2), rx.recv().await);
63 }
64
65 #[cfg_attr(not(target_arch = "wasm32"), tokio::test)]
67 #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
68 async fn all_spawned_tasks_run() {
69 let (tx, mut rx) = mpsc::channel(3);
70 for i in 0..3 {
71 let tx = tx.clone();
72 spawn(async move {
73 tx.send(i).await.unwrap();
74 });
75 }
76 drop(tx);
77
78 let mut received = Vec::new();
79 while let Some(i) = rx.recv().await {
80 received.push(i);
81 }
82 received.sort();
83 assert_eq!(vec![0, 1, 2], received);
84 }
85}
86