I can't come up with decent search terms for this one.
What I'm looking to do is clean up my code so that I can remove identical where clauses from it. Using a couple well-known traits as placeholders, imagine:
enum Stuff<T, U> where T: Clone + Debug, U: Clone + Display {...}
struct Things<T, U> where T: Clone + Debug, U: Clone + Display {...}
fn do_stuff_and_things<T, U>(t: T) -> u: U where T: Clone + Debug, U: Clone+Display {...}
Obviously, I'm getting a lot of duplicate Clone + Debug
and Clone + Display
in there. I'm looking for a way to reduce that, both for readability, and also because, maybe someday I'll want one of these to have the Read and Write traits as well.
I thought of creating a new trait with them as supertraits like so:
trait CloneDebug: Clone + Debug {};
trait CloneDisplay: Clone + Display{};
fn do_stuff_and_things<T: CloneDebug, U: CloneDisplay>(t: T) -> u: U {...}
But I think this restricts what I can actually accept. The first version allowed do_stuff_and_things
to operate on any traits that implement Clone
and Debug
, whereas the second version will only operate on traits that explicitly implement CloneDebug
. So I wouldn't be able to pass String
into it, even though it implements all three traits.
I tried type CloneDebug = Clone + Debug;
but Rust found it offensive and I'm inclined to agree. I've looked at the newType pattern, but for this particular usecase, that seems to be adding, not removing coding overhead.
Is there some other way to specify a "trait alias"?