Announcing enum-map 0.2

So, I decided to make a small crate, and well, enum-map allows using C-style enum values as array keys in a type safe way (you cannot use wrong enum). Similar facilities do exist in languages like C (C99, {[KEY] = value}) or Go ([5]T{Key = value}), but they aren't exactly type safe (as arrays still have integers as keys). This on the other hand is - because it's Rust with its focus on safety.

Having an enum as array key without this module involved either using usize as array key (which is problematic, as it requires user to know size of enum, as well as it requires casting, and Rust doesn't provide usize to C style enum cast) or a hash map, which had a performance cost of a hash map (this is a systems programming language, why use a hash map when you don't need to).

https://crates.io/crates/enum-map

This crate also uses procedural macros for generating an implementation of crate internal trait, which currently (?) have to be in a separate crate.

https://crates.io/crates/enum-map-derive

This is my first crate as mentioned on What's everyone working on this week (20/2017)? - #2 by xfix, so I hope it is useful.

Example of usage:

#[macro_use]
extern crate enum_map;
#[macro_use]
extern crate enum_map_derive;

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

fn main() {
    let map = enum_map! {
        Example::A | Example::B => 1,
        Example::C => 2,
        // Note that all variants have to be considered
        // while constructing, otherwise an error happens
        _ => 3,
    };
    assert_eq!(map[Example::D], 3);
}

6 Likes

Hey thanks! I actually just needed this for a state machine table, so its great.

1 Like

This is very cool. Would you consider adding a Readme to the repository? Also, I was wondering whether the underlying representation is a dense array (with one element per enum variant), a sparse array (of key/value pairs), or a hash map? Depending on the size of the map & sparsity of the keyspace, each encoding could make sense.

1 Like

A dense array. For instance:

enum Example { A, B, C }
enum_map! {
    Example::A => 1,
    Example::B => 2,
    Example::C => 3,
}

Is internally represented as this:

[1, 2, 3]

(all values have to be defined, this allows for such a representation, but more importantly, avoids having to deal with Options in typical case or worse, sudden panics, like in HashMap)

There is no support for sparse arrays, but that may be looked into the future (as an alternate type), however I don't think it would be all that useful (but perhaps I'm wrong?). Hash maps won't be used, you can simply use a hash map for that :slight_smile: