Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No way to map enum? #196

Open
lattice0 opened this issue Oct 1, 2020 · 6 comments
Open

No way to map enum? #196

lattice0 opened this issue Oct 1, 2020 · 6 comments
Labels

Comments

@lattice0
Copy link

lattice0 commented Oct 1, 2020

Hi, it's not possible to map with enum keys?

pub enum AVPixelFormat {
    AV_PIX_FMT_NONE=-1,
    AV_PIX_FMT_YUV420P,   ///< planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
    AV_PIX_FMT_YUYV422,   ///< packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
    //...


static KEYWORDS: phf::Map<AVPixelFormat, PixelFormat> = phf_map! {
    AVPixelFormat::AV_PIX_FMT_YUV420P => PixelFormat {
    //...

error: unsupported key expression
  --> src/common/pixel_formats_impl.rs:29:5
   |
29 |     AVPixelFormat::AV_PIX_FMT_YUV420P => PixelFormat {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@robatipoor
Copy link

I have the same problem why not support enum as key map?

@chpio
Copy link

chpio commented Apr 15, 2021

No, being a preprocessor/macro means that it needs to have direct access to the value of the key (phf is "reading" the keys from the source code), there's no way for it to access rust types & values indirectly, it needs to be a simple rust literal. phf needs the value of the key to hash it at compile time.

Take my use case for example: I need to check if an uuid is contained in a set of "hardcoded" uuids. My first approach was to define a const array and use binary search for performance, but that requires that the array is sorted by hand by the developer. phf is easier to use (no need to sort by hand) but now i can't just use uuid::Uuid objects as keys (even tho they can be constructed through a const fn). My workaround is to put uuids represented by u128s into the phf set.

@chpio
Copy link

chpio commented Apr 15, 2021

dup of #188 ?

@Pauan
Copy link

Pauan commented Sep 4, 2023

If you want to use enum keys, there is the enum-map crate.

You can use EnumMap<K, Option<V>> where K is your enum type, and V is the value type.

The Option is to allow for values to not exist (just like a normal hash map):

#[derive(Debug, Enum)]
enum Example {
    A,
    B,
    C,
    D,
}

// Initialize the map with the keys A and B defined, but C and D are not defined.
let mut map = enum_map! {
    Example::A => Some("foo"),
    Example::B => Some("bar"),
    _ => None,
};

// This is the same as `map.get(&Example::C)` in a normal hash map.
let value = &map[Example::C];

// This is the same as `map.insert(Example::C, "qux");` in a normal hash map.
map[Example::C] = Some("qux");

@thomasmost
Copy link

thomasmost commented Jan 9, 2024

If you want to use enum keys, there is the enum-map crate.

You can use EnumMap<K, Option<V>> where K is your enum type, and V is the value type.

Does this work with static constant declarations (because that's the whole point of phf)?

I think the answer is no, which means this is not a good solution for someone having difficulty declaring static enum maps using phf

@Pauan
Copy link

Pauan commented Jan 9, 2024

@thomasmost Unfortunately it cannot be used directly in a static or const.

However, using Lazy (or lazy_static!) works fine:

use once_cell::sync::Lazy;
use enum_map::{Enum, EnumMap, enum_map};

#[derive(Debug, Enum)]
enum Example {
    A,
    B,
    C,
    D,
}

static FOO: Lazy<EnumMap<Example, Option<&'static str>>> = Lazy::new(|| enum_map! {
    Example::A => Some("foo"),
    Example::B => Some("bar"),
    _ => None,
});

fn main() {
    println!("{:?}", FOO[Example::A]);
    println!("{:?}", FOO[Example::B]);
    println!("{:?}", FOO[Example::C]);
}

And using Lazy<Mutex<EnumMap<...>>> for mutability also works fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants