trait MyIface { fn foo(&self); fn bar(&self, x: i32); fn baz(&self, y: String, z: Vec); } struct Implementor {} impl MyIface for Implementor { fn foo(&self) { dbg!("foo"); } fn bar(&self, x: i32) { dbg!("bar", x); } fn baz(&self, y: String, z: Vec) { dbg!("baz", y, z); } } // Begin of the part which is supposed to be auto-generated enum MyIfaceEnum { Foo, Bar { x: i32 }, Baz { y: String, z: Vec }, } impl MyIfaceEnum { fn call(self, o: &I) { match self { MyIfaceEnum::Foo => o.foo(), MyIfaceEnum::Bar { x } => o.bar(x), MyIfaceEnum::Baz { y, z } => o.baz(y, z), } } #[allow(unused)] fn call_mut(self, o: &mut I) { match self { MyIfaceEnum::Foo => o.foo(), MyIfaceEnum::Bar { x } => o.bar(x), MyIfaceEnum::Baz { y, z } => o.baz(y, z), } } #[allow(unused)] fn call_once(self, o: I) { match self { MyIfaceEnum::Foo => o.foo(), MyIfaceEnum::Bar { x } => o.bar(x), MyIfaceEnum::Baz { y, z } => o.baz(y, z), } } } trait MyIfaceResultified { fn try_foo(&self) -> Result<(), E>; fn try_bar(&self, x: i32) -> Result<(), E>; fn try_baz(&self, y: String, z: Vec) -> Result<(), E>; } impl> MyIface for R { fn foo(&self) { R::try_foo(self).unwrap() } fn bar(&self, x: i32) { R::try_bar(self, x).unwrap() } fn baz(&self, y: String, z: Vec) { R::try_baz(self,y,z).unwrap() } } struct MyIfaceProxy Result<(), E> > (F); impl Result<(), E>> MyIfaceResultified for MyIfaceProxy { fn try_foo(&self) -> Result<(), E> { self.0(MyIfaceEnum::Foo) } fn try_bar(&self, x: i32) -> Result<(), E> { self.0(MyIfaceEnum::Bar { x }) } fn try_baz(&self, y: String, z: Vec) -> Result<(), E> { self.0(MyIfaceEnum::Baz { y, z }) } } // End of the part which is supposed to be auto-generated #[test] fn simple() { let o = Implementor {}; let p = MyIfaceProxy::(|c| Ok(c.call(&o))); p.foo(); p.bar(4); }