Created
November 12, 2021 18:30
-
-
Save cdata/c18be468aa04b2794d4109408dad4d00 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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