crossmist 1.1.2

Efficient and seamless cross-process communication, both synchronously and asynchronously
Documentation
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>) -> i32 {
        let a = rx.recv().await.unwrap().unwrap();
        let b = rx.recv().await.unwrap().unwrap();
        a - b
    }
    let (mut tx, rx) = channel::<i32>().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<i32>) {
        tx.send(&5).await.unwrap();
        tx.send(&7).await.unwrap();
    }
    let (tx, mut rx) = channel::<i32>().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<i32, (i32, i32)>) {
        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<Receiver<i32>>) -> i32 {
        let mut chan1 = chan.recv().await.unwrap().unwrap();
        chan1.recv().await.unwrap().unwrap()
    }
    let (mut tx, rx) = channel::<i32>().unwrap();
    let (mut tx1, rx1) = channel::<Receiver<i32>>().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<i32>, 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(), ());
}