chorus_lib 0.5.0

Choreographic Programming in Rust
Documentation
extern crate chorus_lib;
use std::fmt::Debug;
use std::thread;

use chorus_lib::core::{
    ChoreoOp, Choreography, ChoreographyLocation, Located, LocationSet, Portable, Projector,
};
use chorus_lib::transport::local::{LocalTransport, LocalTransportChannelBuilder};

#[derive(ChoreographyLocation)]
struct Alice;
#[derive(ChoreographyLocation)]
struct Bob;
#[derive(ChoreographyLocation)]
struct Carol;

struct CommAndPrint<V: Portable, L1: ChoreographyLocation, L2: ChoreographyLocation> {
    sender: L1,
    receiver: L2,
    data: Located<V, L1>,
}

impl<V, L1, L2> Choreography<Located<V, L2>> for CommAndPrint<V, L1, L2>
where
    V: Portable + Debug,
    L1: ChoreographyLocation,
    L2: ChoreographyLocation,
{
    type L = LocationSet!(L1, L2);
    fn run(self, op: &impl ChoreoOp<Self::L>) -> Located<V, L2> {
        let v = op.comm(self.sender, self.receiver, &self.data);
        op.locally(self.receiver, |un| println!("{:?}", un.unwrap(&v)));
        v
    }
}

struct MainChoreography;

impl Choreography<Located<i32, Alice>> for MainChoreography {
    type L = LocationSet!(Alice, Bob);

    fn run(self, op: &impl ChoreoOp<Self::L>) -> Located<i32, Alice> {
        let v1 = op.locally(Alice, |_| 100);
        let v2 = op.call(CommAndPrint {
            sender: Alice,
            receiver: Bob,
            data: v1,
        });
        let v2 = op.locally(Bob, |un| un.unwrap(&v2) + 10);
        return op
            .conclave(CommAndPrint {
                sender: Bob,
                receiver: Alice,
                data: v2,
            })
            .flatten();
    }
}

fn main() {
    let transport_channel = LocalTransportChannelBuilder::new()
        .with(Alice)
        .with(Bob)
        .with(Carol)
        .build();

    let mut handles = vec![];
    {
        let transport = LocalTransport::new(Alice, transport_channel.clone());
        handles.push(thread::spawn(|| {
            let p = Projector::new(Alice, transport);
            let v = p.epp_and_run(MainChoreography);
            assert_eq!(p.unwrap(v), 110);
        }));
    }
    {
        let transport = LocalTransport::new(Bob, transport_channel.clone());
        handles.push(thread::spawn(|| {
            let p = Projector::new(Bob, transport);
            p.epp_and_run(MainChoreography);
        }));
    }
    for h in handles {
        h.join().unwrap();
    }
}