Copy is hard/impossible generically, without exposing the [T; 10]
. E.g.
impl<T, S: Storage> Copy for MyStructure<T, S> where S::Container<[T; 10]>: Copy {}
would “expose” that type. For the case at hand, where only the two kinds of storage exist, one of which is never Copy
, one could write a Copy
impl for the concrete type
impl<T: Copy> Copy for MyStructure<T, Direct> {}
For Clone
, you can write a trait bound for the S
parameter, which is probably the nicest looking approach since no bounds on S::Container<[T; 10]>
are involved then. I.e. some trait SupportsCloneStorage
could allow
impl<T: Clone, S: SupportsCloneStorage> Clone for MyStructure<T, S> { … }
However, again assuming that we only want to have the Direct
and Boxed
storage anyways, both of which are clonable, we can make it part of Storage
itself, so we have
impl<T: Clone, S: Storage> Clone for MyStructure<T, S> { … }
How to do this: Since it’s impossible/hard to write something like “this shall be Clone
for all parameters T: Clone
” on a GAT, the easiest approach is to introduce a helper method to Storage
trait and just use that.
pub trait Storage {
type Container<T>: From<T>;
fn clone<T: Clone>(this: &Self::Container<T>) -> Self::Container<T>;
}
impl<T: Clone, S: Storage> Clone for MyStructure<T, S> {
fn clone(&self) -> Self {
Self {
data: S::clone(&self.data),
}
}
}
Rust Playground