Peternator7 / strum

A small rust library for adding custom derives to enums
https://crates.io/crates/strum
MIT License
1.8k stars 151 forks source link

Accessing the EnumTable type through the enum #354

Open zargad opened 6 months ago

zargad commented 6 months ago

I would like to access the *Table type generated by EnumTable through the enum itself.

My main reason is that it would be possible to use them with their respective enum as generics. (example below) In addition, it would reduce the problem of name mangling in situations where the type *Table already exists (I don't know how much of a problem it is, or if that would make the name mangling redundant).

Here is an example of code that would be possible with that feature:

#[derive(EnumTable)]
enum Fruits {
    Apples,
    Oranges,
    Bananas,
}

struct Shop<I: EnumTable> {
    prices: I::Table<u32>,
    best_item: I,
}

impl<I: EnumTable> Shop<I> {
    fn get_best_item_price(&self) -> u32 {
        self.prices[self.best_item]
    }
}

let fruit_shop = Shop<Fruits> { 
    prices: Fruits::Table::new(32, 16, 9),  
    best_item: Fruits::Bananas,
};
assert_eq!(fruit_shop.get_best_item_price(), 9);
zargad commented 6 months ago

I just realized that this will create a new problem if there is a variant with the name Table.

An implementation that solves this would be to make the enum accessible from the table, and not the other way around:

#[derive(EnumTable)]
enum Furniture {
    Chair,
    Lamp,
    Table,
}

struct Shop<I: EnumTableTrait> {
    prices: I,
    best_item: I::Enum,
}

impl<I: EnumTableTrait> Shop<I> {
    fn get_best_item_price(&self) -> u32 {
        self.prices[self.best_item]
    }
}

let furniture_shop = Shop<FurnitureTable> { 
    prices: FurnitureTable::new(32, 16, 9),  
    best_item: Furniture::Table,
};
assert_eq!(fruit_shop.get_best_item_price(), 9);