Sure, but that only works for static dispatch. It doesn't work with for example a heterogeneous Vec<Thing<_>>. For that, I'm currently adding a dynamic dispatch wrapper trait DynamicThing that is implemented for all Thing<Error=E> and implements Thing<Error=Box<Error>>. Then, I can have a Vec<Box<DynamicThing>>. I find it difficult to implement, though, so I was asking whether there is a simpler solution.
For reference, here is my implementation:
use std::io::Error as IoError;
use std::error::Error;
trait Trait {
type Error;
fn do_it(&self);
}
struct DynamicThing<E: Error, T: Trait<Error = E>> {
thing: T
}
impl<E: Error, T: Trait<Error = E>> Trait for DynamicThing<E, T> {
type Error = Box<Error>;
fn do_it(&self) {
self.thing.do_it()
}
}
impl<'a, E: Error, T: Trait<Error = E>> From<T> for DynamicThing<E, T> {
fn from(thing: T) -> DynamicThing<E, T> {
DynamicThing { thing: thing }
}
}
struct Thing {
}
impl Trait for Thing {
type Error = IoError;
fn do_it(&self) {
println!("Do one thing")
}
}
struct ThingTwo {
}
impl Trait for ThingTwo {
type Error = IoError;
fn do_it(&self) {
println!("Do another thing")
}
}
fn main() {
let thing_one = DynamicThing::from(Thing {});
let thing_two = DynamicThing::from(ThingTwo {});
let things: Vec<&Trait<Error = _>> = vec![&thing_one, &thing_two];
for thing in things {
thing.do_it();
}
}