72 lines
1.5 KiB
Rust
72 lines
1.5 KiB
Rust
use effers::program;
|
|
|
|
#[program(Incrementer(increment(&self)), Printer(print(&self)))]
|
|
fn prog(val: u8) -> u8 {
|
|
let x = increment(val);
|
|
let y = increment(x);
|
|
|
|
print(x);
|
|
|
|
x + y
|
|
}
|
|
|
|
pub trait Incrementer {
|
|
fn increment(&self, v: u8) -> u8;
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub struct TestInc;
|
|
impl Incrementer for TestInc {
|
|
fn increment(&self, v: u8) -> u8 {
|
|
v + 3
|
|
}
|
|
}
|
|
|
|
trait Printer {
|
|
fn print(&self, s: u8);
|
|
}
|
|
|
|
#[derive(Clone, Copy)]
|
|
struct Printer1;
|
|
impl Printer for Printer1 {
|
|
fn print(&self, s: u8) {
|
|
println!("1: {}", s)
|
|
}
|
|
}
|
|
#[derive(Clone)]
|
|
struct Printer2 {
|
|
prefix: String,
|
|
}
|
|
impl Printer for Printer2 {
|
|
fn print(&self, s: u8) {
|
|
println!("2: {} {}", self.prefix, s)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
// if a program only has Clone effects, the program also becomes clone
|
|
// same applies for Copy
|
|
|
|
// a is Copy since TestInc is Copy
|
|
let a = Prog.add(TestInc);
|
|
|
|
let b = a.add(Printer1);
|
|
let c = a.add(Printer2 {
|
|
prefix: "this is a number".to_string(),
|
|
});
|
|
|
|
// both TestInc and Printer1 are Copy,
|
|
// therefore b is copy, and we can call it as much as we want
|
|
let first_result = b.run(0);
|
|
assert_eq!(first_result, 9);
|
|
let second_result = b.run(2);
|
|
assert_eq!(second_result, 13);
|
|
|
|
// since Printer2 is not Copy, but it is Clone,
|
|
// c is Clone but not Copy
|
|
let first_result = c.clone().run(0);
|
|
assert_eq!(first_result, 9);
|
|
let second_result = c.run(2);
|
|
assert_eq!(second_result, 13);
|
|
}
|