I'm working on some code that uses dynamic polymorphism extensively. To clone trait instances I've end up using many copies of the "clone to Box" pattern suggested in various places (SO: "How to clone a struct storing a trait object?", users.rust-lang: "Is it possible to clone a boxed trait object?"), viz.:
trait Trait: TraitClone {}
trait TraitClone {
fn clone_to_box(&self) -> Box<Trait>;
}
impl<T> TraitClone for T where T: 'static + Trait + Clone {
fn clone_to_box(&self) -> Box<Trait> {
Box::new(self.clone())
}
}
impl Clone for Box<Trait> {
fn clone(&self) -> Box<Trait> {
self.clone_to_box()
}
}
#[derive(Clone)]
struct Impl {}
impl Trait for Impl {}
As I say I have many uses of this pattern. Each struct that implements Trait
just needs a #[derive(Clone)]
, which is really slick; but every Trait
needs a sibling trait and two impl blocks duplicated, which I'd like to improve.
Generic CloneToBox
I managed to write a generic trait CloneToBox<T>
to replace TraitClone
:
trait CloneToBox {
type Boxed;
fn clone_to_box(&self) -> Box<Self::Boxed>;
}
impl<T> CloneToBox for T where T: Clone {
type Boxed = T;
fn clone_to_box(&self) -> Box<Self::Boxed> {
Box::new(self.clone())
}
}
trait Trait: CloneToBox {}
// Rest as before
I'm amazed that this compiles (see Rust playground), as with a plain generic type on CloneToBox (not an associated type) compilation fails citing a circular reference in Trait
's supertraits.
This seems a little cleaner than my first approach and is shorter than the other implementations I've found while searching. Any thoughts on putting this in a crate or the standard library?