use crossmist::tokio::{channel, duplex, Duplex, Receiver, Sender}; use crossmist::{FnOnceObject, Object}; #[ctor::ctor] fn ctor() { crossmist::init(); } #[derive(Debug, PartialEq, Object)] struct SimplePair { x: i32, y: i32, } #[tokio::test(flavor = "current_thread")] async fn simple() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner() -> i64 { 0x123456789abcdef } assert_eq!(inner.run_tokio().await.unwrap(), 0x123456789abcdef); assert_eq!( inner.spawn_tokio().await.unwrap().join().await.unwrap(), 0x123456789abcdef ); } #[tokio::test(flavor = "current_thread")] async fn add_with_arguments() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(x: i32, y: i32) -> i32 { x + y } assert_eq!(inner.call_object_once((5, 7)).await, 12); assert_eq!( inner.spawn_tokio(5, 7).await.unwrap().join().await.unwrap(), 12 ); } #[tokio::test(flavor = "current_thread")] async fn swap_complex_argument() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(pair: SimplePair) -> SimplePair { SimplePair { x: pair.y, y: pair.x, } } assert_eq!( inner .spawn_tokio(SimplePair { x: 5, y: 7 }) .await .unwrap() .join() .await .unwrap(), SimplePair { x: 7, y: 5 } ); } #[tokio::test(flavor = "current_thread")] async fn with_passed_rx() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(mut rx: Receiver) -> i32 { let a = rx.recv().await.unwrap().unwrap(); let b = rx.recv().await.unwrap().unwrap(); a - b } let (mut tx, rx) = channel::().unwrap(); let child = inner.spawn_tokio(rx).await.unwrap(); tx.send(&5).await.unwrap(); tx.send(&7).await.unwrap(); assert_eq!(child.join().await.unwrap(), -2); } #[tokio::test(flavor = "current_thread")] async fn with_passed_tx() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(mut tx: Sender) { tx.send(&5).await.unwrap(); tx.send(&7).await.unwrap(); } let (tx, mut rx) = channel::().unwrap(); let child = inner.spawn_tokio(tx).await.unwrap(); assert_eq!( rx.recv().await.unwrap().unwrap() - rx.recv().await.unwrap().unwrap(), -2 ); child.join().await.unwrap(); } #[tokio::test(flavor = "current_thread")] async fn with_passed_duplex() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(mut chan: Duplex) { while let Some((x, y)) = chan.recv().await.unwrap() { chan.send(&(x - y)).await.unwrap(); } } let (mut local, downstream) = duplex::<(i32, i32), i32>().unwrap(); let child = inner.spawn_tokio(downstream).await.unwrap(); for (x, y) in [(5, 7), (100, -1), (53, 2354)] { local.send(&(x, y)).await.unwrap(); assert_eq!(local.recv().await.unwrap().unwrap(), x - y); } drop(local); child.join().await.unwrap(); } #[tokio::test(flavor = "current_thread")] async fn with_passed_nested_channel() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(mut chan: Receiver>) -> i32 { let mut chan1 = chan.recv().await.unwrap().unwrap(); chan1.recv().await.unwrap().unwrap() } let (mut tx, rx) = channel::().unwrap(); let (mut tx1, rx1) = channel::>().unwrap(); tx.send(&5).await.unwrap(); tx1.send(&rx).await.unwrap(); assert_eq!(inner.run_tokio(rx1).await.unwrap(), 5); } #[tokio::test(flavor = "current_thread")] async fn with_async_write() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner(mut tx_data: Sender, mut tx_signal: Sender<()>) { let future = tokio::spawn(async move { for i in 0..1000 { tx_data.send(&i).await.unwrap(); } }); tx_signal.send(&()).await.unwrap(); future.await.unwrap(); } let (tx_data, mut rx_data) = channel().unwrap(); let (tx_signal, mut rx_signal) = channel().unwrap(); let child = inner.spawn_tokio(tx_data, tx_signal).await.unwrap(); rx_signal.recv().await.unwrap(); for i in 0..1000 { assert_eq!(rx_data.recv().await.unwrap().unwrap(), i); } child.join().await.unwrap(); } #[tokio::test(flavor = "current_thread")] async fn exitting() { #[crossmist::func(tokio(flavor = "current_thread"))] async fn inner() { std::process::exit(0); } assert_eq!(inner.run_tokio().await.unwrap(), ()); }