I have a feeling that this is either trivial or impossible.
I want to create a type that shall be generic over some container type but not over their content. Imagine being able to choose between Arc
or Rc
for the fields but the public interface has no knowledge about the inner types.
My first attempt using generics:
struct BlueContainer<T>(T);
struct RedContainer<T>(T);
trait GetInner<T> { fn get(&self) -> T; }
impl<T> GetInner<T> for BlueContainer<T> {
fn get(&self) -> T { self.0 }
}
impl<T> GetInner<T> for RedContainer<T> {
fn get(&self) -> T { self.0 }
}
// Is there a way to express that `Variable` shall not be bound to a certain type
struct Carrier<C<Variable>: GetInner<Variable>> {
colorblind_string_container: C<String>,
colorblind_int_container: C<i32>,
red_string_container: RedContainer<String>,
blue_int_container: BlueContainer<i32>,
}
My second attempt using associated types
struct BlueContainer<T>(T);
struct RedContainer<T>(T);
trait GetInner {
type Inner;
fn get(&self) -> &Self::Inner;
}
impl<T> GetInner for BlueContainer<T> {
type Inner = T;
fn get(&self) -> &Self::Inner { &self.0 }
}
impl<T> GetInner for RedContainer<T> {
type Inner = T;
fn get(&self) -> &Self::Inner { &self.0}
}
struct Carrier<C> where C: GetInner {
colorblind_int_container: C, // should be something like `C::<i32>`
colorblind_string_container: C, // should be something like `C::<String>`
}
fn main() {
let carrier = Carrier {
colorblind_int_container: BlueContainer(123_i32),
// fails because BlueContainer has been used as i32 already
colorblind_string_container: BlueContainer("asdf".to_owned()),
};
println!("{}", carrier.colorblind_int_container.get());
println!("{}", carrier.colorblind_string_container.get());
}