effers/examples/clone.rs

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);
}