trait MyIface { fn foo(&self) -> String; fn bar(&self, x: i32) -> i32; fn baz(&self, y: String, z: Vec); } struct Implementor {} impl MyIface for Implementor { fn foo(&self) -> String { dbg!("foo"); "qqq".to_owned() } fn bar(&self, x: i32) -> i32 { dbg!("bar", x); x*x+1 } 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 { ret: flume::Sender }, Bar { x: i32, ret: flume::Sender }, Baz { y: String, z: Vec }, } impl MyIfaceEnum { fn try_call(self, o: &I) -> Result<(), &'static str> { match self { MyIfaceEnum::Foo {ret} => Ok(ret.send(o.foo()).map_err(|_|"Failed to return value though enumizer channel")?), MyIfaceEnum::Bar { x, ret } => Ok(ret.send(o.bar(x)).map_err(|_|"Failed to return value though enumizer channel")?), MyIfaceEnum::Baz { y, z } => Ok(o.baz(y, z)), } } } trait MyIfaceResultified { fn try_foo(&self) -> Result, E1>; fn try_bar(&self, x: i32) -> Result, E1>; fn try_baz(&self, y: String, z: Vec) -> Result<(), E1>; } impl> MyIface for R { fn foo(&self) -> String { R::try_foo(self).unwrap().unwrap() } fn bar(&self, x: i32) -> i32 { R::try_bar(self, x).unwrap().unwrap() } fn baz(&self, y: String, z: Vec) { R::try_baz(self,y,z).unwrap() } } struct MyIfaceProxy Result<(), E1>> (F1); impl Result<(), E1> > MyIfaceResultified for MyIfaceProxy { fn try_foo(&self) -> Result, E1> { let (tx, rx) = flume::bounded(1); self.0(MyIfaceEnum::Foo{ret:tx})?; Ok(rx.recv()) } fn try_bar(&self, x: i32) -> Result, E1> { let (tx, rx) = flume::bounded(1); self.0(MyIfaceEnum::Bar { x, ret: tx })?; Ok(rx.recv()) } fn try_baz(&self, y: String, z: Vec) -> Result<(), E1> { 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| c.try_call(&o)); dbg!(p.try_foo().unwrap().unwrap()); dbg!(p.try_bar(4).unwrap().unwrap()); }