Is there a way to implement a Trait with a generic type T for an enum? something like this:
use rand::thread_rng;
use rand::seq::SliceRandom;
pub enum Color {
Red,
Blue,
Green,
}
trait Shuffable {
fn values<T>() -> Vec<T>;
fn shuffled<T: Shuffable>() -> Vec<T> {
let mut items = T::values();
items.shuffle(&mut thread_rng());
items
}
}
impl Shuffable for Color {
fn values<Color>() -> Vec<Color> {
vec![Color::Red, Color::Blue, Color::Green]
}
}
This errors on not being able to relate Enum items to the Type itself
error[E0599]: no associated item named `Red` found for type parameter `Color` in the current scope
--> src/game.rs:25:21
|
25 | vec![Color::Red, Color::Blue, Color::Green]
| ^^^ associated item not found in `Color`
error[E0599]: no associated item named `Blue` found for type parameter `Color` in the current scope
--> src/game.rs:25:33
|
25 | vec![Color::Red, Color::Blue, Color::Green]
| ^^^^ associated item not found in `Color`
error[E0599]: no associated item named `Green` found for type parameter `Color` in the current scope
--> src/game.rs:25:46
|
25 | vec![Color::Red, Color::Blue, Color::Green]
| ^^^^^ associated item not found in `Color`
I have checked https://github.com/rust-lang/rust/issues/52118 but it doesn't seem to be related!
As a starting point, we can make your code work as follows:
use rand::thread_rng;
use rand::seq::SliceRandom;
#[derive(Debug)]
pub enum Color {
Red,
Blue,
Green,
}
trait Shuffable where Self: Sized {
fn values() -> Vec<Self>;
fn shuffled() -> Vec<Self> {
let mut items = Self::values();
items.shuffle(&mut thread_rng());
items
}
}
impl Shuffable for Color {
fn values() -> Vec<Self> {
vec![Color::Red, Color::Blue, Color::Green]
}
}
fn main() {
let shuffled = Color::shuffled();
println!("{:?}", shuffled)
}
Self
has to be sized since the concrete type that is implementing Shuffable
needs to be stored inside a vector and we need to know how much space we are allocating.
I think the point of confusion may be with the generic parameter T
, I assume you were thinking that this is for representing the Color
type? If so, this is not necessary since the type for which you are implementing the trait is represented through Self
. T
introduces another type which is not constrained anywhere.