I am working on a project in which I'm using methods from a number of crates Foo1, Foo2, etc., returning objects like Result<T,Foo1Error>, Result<T,Foo2Error>, respectively, within an implementation of a trait from another crate Bar, whose methods must return Result<U,BarError>. Because Foo1, Foo2, and Bar are all external, I cannot implement impl From<Foo1Error> for BarError or ditto for for Foo2Error due to the orphan rule. The popular third-party crates for error handling (error_chain, thiserror, etc.) don't look to me like they help, since they are generally for creating new error types and I'm stuck with having to return BarError. So, I've defined functions like foo1err_to_barerr and foo2err_to_barerr and my code is littered with dozens of chains involving .map_err(foo1err_to_barerr)?.
While it works perfectly well, this visually clutters up the logical parts of the code quite a bit. Are there any alternative techniques that move some of the error mapping boilerplate out of the logical parts of code? If I only had Foo1Error to worry about, for each trait method I'm implementing I'd just make separate method that returned Result<U,Foo1Error> and then all the trait method would do would map the error (collapsing multiple map_err calls into one). But, I have multiple external error types to deal with, and so that new helper method would have to return a boxed error, or a custom error enum, and between the duplication of methods and new compound error types I think I wouldn't (personally) prefer that style any more.
If I permit myself to dream up some blue sky syntax (of course not something Rust supports) would be the ability to define error mapping that happens when the function scope exits: in the meat of the method I could just use ? to my heart's content, and then state once how each error type coming from a ? has to map to the returned Result's error type.
I kept everything above generic, but in case there is a particular solution rather than a general one, the "Bar" crate is actually tonic and BarError is actually tonic::Status.