// WIP: Chainable function transformations with a builder pattern API. // Potentially useful for reusing image processing code struct Trigger { func: Box Current>, } struct Image; impl Trigger { fn new() -> Trigger { Trigger { func: Box::new(|x| x), } } } impl Trigger { fn map(self, f: impl Fn(Current) -> X + 'static) -> Trigger { Trigger { func: Box::new(move |x| f((self.func)(x))), } } fn run(&self, root: Root) -> Current { (self.func)(root) } } impl Trigger { fn crop(self, _x: u32, _y: u32, _w: u32, _h: u32) -> Trigger { self } fn threshold(self, _r: u8, _g: u8, _b: u8, _threshold: u8) -> Trigger { self } fn ocr(self) -> Trigger { Trigger { func: Box::new(|_| "".to_string()), } } } impl Trigger { fn regex(self, _pattern: &str) -> Trigger { Trigger { func: Box::new(|_| true), } } } fn image_trigger() -> Trigger { Trigger::new() } fn main() { image_trigger() // identity function on Image .crop(0, 0, 100, 100) // identity, then crop .threshold(255, 255, 255, 42) // identity => crop => threshold .ocr() // ... .regex("asdf") .map(|_| println!("Triggered!")) .run(Image); let my_string = Trigger::::new() .map(|x| format!("({})", x)) .map(|x| format!("[{}]", x)) .map(|x| format!("{}!", x)) .run("asdf".to_string()); println!("{}", my_string); assert!(my_string == "[(asdf)]!"); let _trigger = Trigger::::new(); image_trigger().run(Image); }