Skip to content

Instantly share code, notes, and snippets.

@cdata
Created November 12, 2021 18:30
Show Gist options
  • Save cdata/c18be468aa04b2794d4109408dad4d00 to your computer and use it in GitHub Desktop.
Save cdata/c18be468aa04b2794d4109408dad4d00 to your computer and use it in GitHub Desktop.
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;
use lunatic::{
process::{self, Process},
Mailbox,
};
use serde::{Deserialize, Serialize};
#[lunatic::main]
fn main(mailbox: Mailbox<Value<i32>>) {
let this = process::this(&mailbox);
let (l, r) = make_sum_process(this);
let l_value = Value::Some(1);
let r_value = Value::Some(2);
l.send(l_value.clone());
r.send(r_value.clone());
let result = mailbox.receive().unwrap();
println!("{} + {} = {}", l_value, r_value, result);
}
#[derive(Serialize, Deserialize, Clone)]
enum Value<T>
where
T: Display,
{
Some(T),
None,
Void,
}
impl<T> Display for Value<T>
where
T: Display,
{
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
if let Value::Some(value) = self {
write!(f, "{}", value)
} else {
write!(f, "")
}
}
}
fn make_sum_process(output: Process<Value<i32>>) -> (Process<Value<i32>>, Process<Value<i32>>) {
let sum = process::spawn_with(output, sum_process).unwrap();
let l = process::spawn_with(sum.clone(), l_inlet).unwrap();
let r = process::spawn_with(sum, r_inlet).unwrap();
(l, r)
}
fn l_inlet(host: Process<(Value<i32>, Value<i32>)>, mb: Mailbox<Value<i32>>) {
while let Ok(value) = mb.receive() {
host.send((value, Value::Void));
}
}
fn r_inlet(host: Process<(Value<i32>, Value<i32>)>, mb: Mailbox<Value<i32>>) {
while let Ok(value) = mb.receive() {
host.send((Value::Void, value));
}
}
fn sum_process(out: Process<Value<i32>>, mb: Mailbox<(Value<i32>, Value<i32>)>) {
let mut l_value = Value::None;
let mut r_value = Value::None;
while let Ok((next_l_value, next_r_value)) = mb.receive() {
match next_l_value {
Value::Void => (),
_ => l_value = next_l_value,
};
match next_r_value {
Value::Void => (),
_ => r_value = next_r_value,
};
match (&l_value, &r_value) {
(Value::Some(l), Value::Some(r)) => out.send(Value::Some(sum(*l, *r))),
_ => (),
};
}
}
fn sum<T>(l: T, r: T) -> T
where
T: std::ops::Add<Output = T>,
{
l + r
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment