use either_trait_macro::either_trait; #[either_trait] trait Example { fn foo(&mut self, t: T); fn bar(&self, f: F, t: &T) -> T where F: FnOnce(&T) -> T; } struct A; struct B { t: Option, } impl Example for A { fn foo(&mut self, _t: T) {} fn bar(&self, f: F, t: &T) -> T where F: FnOnce(&T) -> T, { f(t) } } impl Example for B { fn foo(&mut self, t: T) { self.t = Some(t); } fn bar(&self, f: F, t: &T) -> T where F: FnOnce(&T) -> T, { f(self.t.as_ref().unwrap_or(t)) } } #[test] fn test_left() { use either::Either; let mut either: Either> = Either::Left(A); either.foo(2); assert_eq!(either.bar(|x| x + 2, &1), 3); } #[test] fn test_right() { use either::Either; let mut either: Either> = Either::Right(B { t: None }); either.foo(2); assert_eq!(either.bar(|x| x + 2, &1), 4); }