Could the error method of ReplyXxx be moved to trait Reply?
Can we add a new error method to the Reply trait, like
fn error(self, err: c_int);
This would allow multiple ReplyXxx types to share the same method implement, as they all currently have this method with identical signature and implement.
More important, it would enable the definition of a unified error handling function, like so:
fn handle_error(err: MyErrorType, reply: impl Reply)
I created a solution that, while not quite exactly what you asked for, pretty much gives you what you wanted: a unified error function. #335
After many months of pondering, I believe I have understood the problem. Reply should not be a trait at all, Reply should be a struct. Similarly, each of the ReplyX should not be structs, they should be traits. This is the more idiomatic way to express the intent behind these methods.
With regards to this git issue (#296), the issue is solved if there is also a ReplyError trait, and each of the other ReplyX traits includes it as a bound.
E.g.
struct Reply {
sender: Channel,
}
impl Reply {
fn new(...) {...}
}
trait ReplyErr {
fn error(...);
}
impl ReplyErr for Reply {
fn error(...) {...}
}
trait ReplyX: ReplyErr {
fn x(...);
}
impl ReplyX for Reply {
fn x(...) {...}
}
This is an API-breaking change, because the Filesystem method signatures go from reply: ReplyX to reply: impl ReplyX.
I argue that the API change is worthwhile because the change has real benefits for application developers. The main benefit to application developers is that the library gets to eliminate one instance of Box<dyn> from every Request, which is at least theoretically, a free speedup. The secondary benefit is that it unlocks application unit testing, since the application developer can implement the traits without needing access to crate-private structs like Channel.