enum-map enum-map xfix/enum-map [enum-map] — An optimized map implementation for enums using an array to store values.

Overview

enum-map

Crates.io Build Status codecov

A library providing enum map providing type safe enum array. It is implemented using regular Rust arrays, so using them is as fast as using regular Rust arrays.

Examples

#[macro_use]
extern crate enum_map;

use enum_map::EnumMap;

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

fn main() {
    let mut map = enum_map! {
        Example::A => 1,
        Example::B => 2,
        Example::C => 3,
    };
    map[Example::C] = 4;

    assert_eq!(map[Example::A], 1);

    for (key, &value) in &map {
        println!("{:?} has {} as value.", key, value);
    }
}
Comments
  • Add licenses for distribution packaging

    Add licenses for distribution packaging

    Symlink the license texts to the crate directories so cargo package would bundle them when packaging.

    Signed-off-by: Michel Alexandre Salim [email protected]

    opened by michel-slm 2
  • Strange code generated in enum_map_derive?

    Strange code generated in enum_map_derive?

    If we have an enum like this:

    pub enum Scens {
        Zero,
        One,
        Two,
        Three,
        Four,
        Five,
    }
    

    doing #[derive(Enum)] produces code that looks like this:

    pub fn from_usize(v: usize) -> Scens {
        use Scens::*;
        if v < 1 {
            Zero
        } else if v < 2 {
            One
        } else if v < 3 {
            Two
        } else if v < 4 {
            Three
        } else if v < 5 {
            Four
        } else if v < 6 {
            Five
        } else {
            unreachable!()
        }
    }
    

    This seems strange to me and the compiler: building with optimisation results in a large chain of comparisons and conditional jumps.

    If instead we would generate

    pub fn from_usize(v: usize) -> Scens {
        use Scens::*;
        if v == 0 {
            Zero
        } else if v == 1 {
            One
        } else if v == 2 {
            Two
        } else if v == 3 {
            Three
        } else if v == 4 {
            Four
        } else if v == 5 {
            Five
        } else {
            unreachable!()
        }
    }
    

    or the less-verbose

    pub fn from_usize(v: usize) -> Scens {
        use Scens::*;
        match v {
            0 => Zero,
            1 => One,
            2 => Two,
            3 => Three,
            4 => Four,
            5 => Five,
            _ => unreachable!()
        }
    }
    

    both of these produce simpler and faster code: check if the value is in range (< 6 in this case) and then accept an answer as-is.

    However I assume the if v < x + 1 implementation wasn't pick at random: is there some information about this? Is there a downside of the proposed methods? It seems very simple to switch the code over to equality check which compiler is much happier about.

    These generated methods are quite hot in our code-base which is how I stumbled upon this.

    Godbolt link: https://rust.godbolt.org/z/a7E3oE81s

    bug 
    opened by Fuuzetsu 2
  • Support for other types

    Support for other types

    Hi, I'm the author of https://docs.rs/plain_enum/latest/plain_enum/, but I'm thinking about adopting enum-map, as it seems to have more traction in the community.

    However, there are some missing bits that I'd like to address.

    This PR adds support for the unit type and for Ordering, which I use in my projects.

    opened by phimuemue 2
  • Stabilize enum-map

    Stabilize enum-map

    For 1.0.0, an Internal interface which will likely be renamed to Enum will need to be stabilized. The plan is once const generics become stable (see https://github.com/rust-lang/rust/issues/44580) - although worth noting that this doesn't need full const generics, just being able to use associated consts within a struct, an Internal trait would be rewritten as such.

    trait Enum {
        const DISCRIMINANTS: usize;
        fn discriminant(self) -> usize;
        fn from_discriminant(discriminant: usize) -> Self;
    }
    
    enhancement 
    opened by xfix 2
  • Fix clippy lints

    Fix clippy lints

    There's a few things that got caught by clippy::pedantic, this is a small PR to eliminate them.

    1. enum-map/src/lib.rs#303: Add #[allow(clippy::unused_self)]

    The self parameter is unused, but the API lines up more closely with other standard data structures to take &self so it makes sense to tell clippy to allow this.

    1. enum-map/tests/serde.rs#61: Remove double-reference to string literal

    This reference was immediately dereferenced by the compiler, so removing it improves code clarity.

    1. enum-map/tests/test.rs#466: Change assert_eq!(val, true) to assert!(val)

    Since there was an equality check against a boolean, it can be expressed instead as assert!.

    opened by caass 1
  • Add a method for converting to an array (not a slice)

    Add a method for converting to an array (not a slice)

    We have from_array, but it would be nice if we could get to_array() if Rust's const implementation allows it (it might not yet, but presumably should at some point).

    opened by norcalli 1
  • enum_map! is unusable as a const initializer, and the array field being private makes manual initialization impossible too

    enum_map! is unusable as a const initializer, and the array field being private makes manual initialization impossible too

    enum_map! is probably not fixable in stable Rust without the unstable const fn support, unless there's some clever approach I'm not seeing.

    However, making the field public would allow to manually do it.

    There's also the possibility of writing an enum_with_map! macro that would create both an enum and an enum map const (by just writing both the variants and the array items in the same order as provided by the user), which is easy and might be good enough in practice.

    Possible implementation of such a macro (after changing EnumMap to be a tuple struct with a public array field):

    #[macro_export]
    macro_rules! enum_with_map {
    	{$(#[$m:meta])* enum $e:ident, const $n:ident : EnumMap<_, $d:ty> = {$($k:ident => $v:expr),*};} => {
            $(#[$m])* #[derive(EnumMap)] enum $e {
                $($k),*
            }
    
            const $n: EnumMap<$e, $d> = EnumMap([
                $($v),*
            ]);
        };
    }
    
    enhancement 
    opened by bill-myers 1
  • Bump actions/dependency-review-action from 2 to 3

    Bump actions/dependency-review-action from 2 to 3

    Bumps actions/dependency-review-action from 2 to 3.

    Release notes

    Sourced from actions/dependency-review-action's releases.

    3.0.0

    Breaking Changes

    By default the action now expects SPDX-compliant licenses everywhere. If you were previously using license names in the allow or deny lists make sure they're valid!

    What's Changed

    Support for external configuration files

    You can now specify a configuration file external to your repository. This allows organizations to have a single configuration file for all their repos.

    Broader license support

    We've added support for a much broader set of project licenses by using GitHub's Licenses API.

    SPDX Compliance

    All of our license-related code now expects SPDX-compliant licenses or expressions. This allows us to standardize on a license naming scheme that already supports OR/AND expressions.

    Disable individual checks

    You can now use the boolean options license-check and vulnerability-check to disable either one of the checks. More information in our configuration options.

    Thanks

    Contributors for this release include:

    Thanks everyone! Full Changelog: https://github.com/actions/dependency-review-action/compare/v2...v3.0.0

    2.5.1

    Adding some quality-of-life improvements to the local development experience. You can now pass a flag to the scripts/scan_pr script using the -c/--config-file flags to use an external configuration file:

    Example:

      scripts/scan_pr https://github.com/actions/dependency-review-action/pull/294
    

    2.5.0

    Fallback on GitHub Licenses API data for missing Dependency Review API Licenses. This should improve our license coverage.

    2.4.1

    This patch release fixes the bugs below:

    • Display the dependency name instead of the manifest name in the detailed list of dependents.
    • Fix an issue where undefined GHSAs would remove filter out all changes.

    ... (truncated)

    Commits
    • 30d5821 Bumping version number
    • 6e42c33 Remove defaults from the recently added fields.
    • a3074cd Merge pull request #327 from actions/adding-extra-options
    • 51a29d6 Updating action.yml to include *-check config
    • 235a221 Merge pull request #324 from actions/readme-update
    • 9b3a7f6 Minor README tweaks.
    • a476131 Add pull_request to the list of events that don't need refs.
    • 28c7c8c Set the correct default for license-check in README.
    • 9da0fd4 Merge pull request #325 from actions/dependabot/npm_and_yarn/eslint-plugin-je...
    • fe45fd6 Merge pull request #326 from actions/dependabot/npm_and_yarn/esbuild-register...
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 0
  • Bump cachix/install-nix-action from 17 to 18

    Bump cachix/install-nix-action from 17 to 18

    Bumps cachix/install-nix-action from 17 to 18.

    Release notes

    Sourced from cachix/install-nix-action's releases.

    install-nix-action-v18

    • Fix nodejs warnings & simplify maintenance
    • Use python3 when determining number of cores
    • Collapse installer log messages
    Commits
    • daddc62 Merge pull request #144 from cachix/fix-ci
    • 8500bf7 try to fix act test
    • 4024cf0 Merge pull request #143 from ggreif/patch-1
    • 3d1155e readme: don't perpetuate old versions
    • e17a164 fix #140: python -> python3
    • 92d3622 Merge pull request #139 from sigprof/collapse-log-output
    • 6c5ba55 install-nix.sh: Collapse log messages
    • 451e611 Merge pull request #134 from lovesegfault/composite-action
    • 112054f refactor: replace with a simpler composite action
    • 24e801e Merge pull request #123 from cachix/dependabot/github_actions/actions/setup-go-3
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 0
  • Bump actions/dependency-review-action from 1 to 2

    Bump actions/dependency-review-action from 1 to 2

    Bumps actions/dependency-review-action from 1 to 2.

    Release notes

    Sourced from actions/dependency-review-action's releases.

    2.0.0

    Major version update! We are introducing a few configuration options to make the action more useful in a broader set of scenarios:

    • fail-on-severity: Specify the minimum security vulnerability threshold before failing workflow runs.
    • allow-licenses: An allowlist for dependency licenses.
    • deny-licenses: A blocklist for dependency licenses.

    You can read more about these options in the "Configuration" section of the README.

    1.0.2

    • Clarify error messages for private repos
    • Update NPM dependencies.

    v1.0.1

    We're starting to use semantic versioning for our project.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies github_actions 
    opened by dependabot[bot] 0
  • Replace EnumArray by generic associated type

    Replace EnumArray by generic associated type

    I read in README that

    library doesn't provide Minimum Supported Rust Version (MSRV).

    If this means that we could use features from stable Rust, here's a PR that eliminates EnumArray, exploiting GADTs. This allows simpler trait bounds (simply Enum instead of EnumArray<V>), which may be valuable for users.

    opened by phimuemue 2
  • Add by-reference array accessors to EnumMap

    Add by-reference array accessors to EnumMap

    An alternative would be to simply expose the array field as pub: whatever works. I went with this as it allows adding simple docs at the same time.

    Fixes #26.

    opened by Fuuzetsu 0
  • Derive Eq, Ord, PartialEq and PartialOrd on EnumMap<K,V> when K and V impl those traits

    Derive Eq, Ord, PartialEq and PartialOrd on EnumMap when K and V impl those traits

    This would be broadly useful when using EnumMap<K,V> inside other structs where it's nice to be able to compare by value. If you think this would be good to add, I'm happy to take a shot, especially if you have some thoughts/opinions on how you think it should be done!

    Thank you!

    opened by klauria-factorial 2
  • Default values for missing fields during deserialization

    Default values for missing fields during deserialization

    Hello. Is there a sensible way to have EnumMap use default values for each key if their key is not present when deserializing from a human-readable format?

    opened by zesterer 2
  • Expose the `array` field (or add `as_array(&self) -> &K::Array`)

    Expose the `array` field (or add `as_array(&self) -> &K::Array`)

    It's currently possible to:

    • Create EnumMap from K::Array with from_array
    • Destructure EnumMap to K::Array with into_array
    • Get a slice reference with as_slice and as_mut_slice

    But it's currently not possible to get a reference to K::Array directly, mutable or not. This is useful if the contents aren't Clone-able but we still want to iterate over the values directly (without concerning ourselves with the keys).

    At this point, it seems that just exposing the array field of EnumMap as public should be fair game: we already have setter/getter and hiding it just makes it inconvenient.

    enhancement 
    opened by Fuuzetsu 7
  • Add Enum for tuples

    Add Enum for tuples

    It seems logical that (A, B) where A: Enum, B: Enum would be basically the same as a struct's derivation, which is a cartesian product. I don't think we're allowed to implement this ourselves as tuples are always a foreign type, but it could be implemented for up to some length of tuples in the crate.

    I personally want this so that I can produce enums via this utility function I've made:

    #[inline(always)]
    pub fn enum_iter<E: enum_map::Enum>() -> impl DoubleEndedIterator<Item = E> + Clone {
        (0..E::LENGTH).map(|i| E::from_usize(i))
    }
    

    without having to nest the enum_iter calls if there's multiple which I want to produce from.

    (Side note: the enum_iter function might also be useful to have put in.)

    I could make an MR if it's an amenable feature to include.

    opened by norcalli 1
Releases(v2.4.2)
  • v2.4.2(Dec 17, 2022)

    Other changes

    • Added license files to crate tarball.
    • Added changelog to crate tarball.

    New Contributors

    • @michel-slm made their first contribution in https://github.com/xfix/enum-map/pull/33

    Full Changelog: https://github.com/xfix/enum-map/compare/v2.4.1...v2.4.2

    Source code(tar.gz)
    Source code(zip)
  • v2.4.1(Jul 29, 2022)

  • v2.4.0(Jun 15, 2022)

  • v2.3.0(May 30, 2022)

    New features

    • EnumMap::len is now usable in const contexts.

    Other changes

    • Enum derive now can deal with re-definitions of usize and unimplemented.
    Source code(tar.gz)
    Source code(zip)
Owner
Konrad Borowski
Currently rarely updated, see https://gitlab.com/KonradBorowski for updates.
Konrad Borowski
A lightweight Rust library for BitVector Rank&Select operations, coupled with a generic Sparse Array implementation

A lightweight Rust library for BitVector Rank&Select operations, coupled with a generic Sparse Array implementation

Alperen Keleş 5 Jun 20, 2022
Array helpers for Rust's Vector and String types

array_tool Array helpers for Rust. Some of the most common methods you would use on Arrays made available on Vectors. Polymorphic implementations for

Daniel P. Clark 69 Dec 9, 2022
Generic array types in Rust

generic-array This crate implements generic array types for Rust. Requires minumum Rust version of 1.36.0, or 1.41.0 for From<[T; N]> implementations

Bartłomiej Kamiński 325 Dec 25, 2022
A hashmap implementation, which uses hashset, and keys are contained within values.

A hashmap implementation, which uses hashset, and keys are contained within values.

Piotr Mikulski 2 Nov 29, 2022
A tree structure in Rust optimized for looking up domain names, with wildcard support

domain-lookup-tree Overview DomainLookupTree is a data structure which provides efficient domain name lookup matching with support for wildcard entrie

null 18 Nov 28, 2022
Some collections to store a fixed number of elements of a specific type.

This repo provide some useful data-structures, such as: Array, HashMap, HashSet, BTreeMap, BTreeSet, etc... That lives on the stack. It's a good choic

null 0 Nov 2, 2022
A simple Vec-based Map inspired on JavaScript for rust.

A simple alternative to HashMap inspired on JavaScript's Map.

Squioole 2 Oct 3, 2021
B-Tree map for pub/sub services

submap B-tree map for pub/sub services. Create a new subscription map let mut smap: SubMap<Client> = SubMap::new(); where "Client" is a pub/sub client

Altertech 6 Sep 21, 2022
Special FUSE filesystem to map /etc/resolv.conf to different files depending on Linux network namespace

Linux network namespaces allow separate networking environment for a group of processes (sharing uid or from a separate user). DNS settings (/etc/resolv.conf) are however shared between all those environments, which may be inconvenient in some setups.

Vitaly Shukela 2 May 16, 2022
Serializable map of any type.

??️ type_reg Serializable map of any type. This library provides a map that can store any serializable type, and retrieve it as the strong type. Seria

Azriel Hoh 3 Dec 26, 2022
Library containing various Data Structures implemented using Rust.

rust-data-structures Library containing various Data Structures implemented using Rust. Running You can test the library by running cargo test, an exa

c1m50c 1 Jan 6, 2022
Conditional compilation using boolean expression syntax, rather than any(), all(), not()

Conditional compilation expressions Conditional compilation using boolean expression syntax, rather than any(), all(), not(). [dependencies] efg = "0.

David Tolnay 298 Dec 28, 2022
Coding-challenge - Algorithms and Data-structures, problems and solutions in Rust language using cargo-workspaces

Coding Challenge LeetCode/Hackerrank e.t.c Using this as an opportunity to improve my knowledge of rust lang If you found this repo useful to you, add

Tolumide Shopein 17 Apr 24, 2022
Roaring bitmap implementation for Rust

RoaringBitmap This is not yet production ready. The API should be mostly complete now. This is a Rust port of the Roaring bitmap data structure, initi

Roaring bitmaps: A better compressed bitset 552 Jan 1, 2023
A proof of concept implementation of cyclic data structures in stable, safe, Rust.

A proof of concept implementation of cyclic data structures in stable, safe, Rust. This demonstrates the combined power of the static-rc crate and the

null 157 Dec 28, 2022
Doubly-Linked List Implementation in Rust

Doubly-Linked List Implementation in Rust Purely for educational and recreational purposes. For real world production please use std::collections::Lin

Tsoding 9 Jul 28, 2022
Hash Table Implementation in Rust

Hash Table Implementation in Rust Purely for educational and recreational purposes. For real world production please use std::collections::HashMap. Fo

Tsoding 11 Sep 6, 2022
Rust implementation of Adobe's stlab::forest data structure

skog Swedish for "forest". A pure rust implementation of Adobe's stlab::forest data structure. Introduction A "forest" is a tree-like data structure.

Julian 1 Dec 8, 2021
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 294 Dec 23, 2022
ndarray: an N-dimensional array with array views, multidimensional slicing, and efficient operations

ndarray The ndarray crate provides an n-dimensional container for general elements and for numerics. Please read the API documentation on docs.rs or t

null 2.6k Jan 7, 2023