#const #map #constant #define #compile-time #associated #maps

const_map

Macro to define compile-time associated constant maps

1 unstable release

0.1.0 May 31, 2023

#2962 in Rust patterns

MIT/Apache

8KB
57 lines

const_map

Define a const map and a const lookup function as associated items of a struct.

When used, if the argument to the lookup function is a constant, the whole lookup will be done at compile-time and replaced with the resulting constant.

If the argument is not a constant, it will still work, but won't be as efficient as an ordinary map, because the lookup is just iterating all elements of the map.

Note that due to current limitations in the Rust standard library and compiler, the key type needs to be an integral type, bool, or char, because other types don't implement PartialEq in a const way yet.

Example:

use const_map::const_map;

struct Fruits {
    name: String,
}

impl Fruits {
    const_map!(MAP, get(), (char => &'static str) {
        'a' => "apple",
        'b' => "banana",
        'c' => "clementine",
        'd' => "durian",
    });
    
    fn new(name: &str) -> Self {
        if let Some(s) = Self::get(name.chars().next().expect("shouldn't be empty")) {
            Self { name: s.to_owned() }
        } else {
            Self { name: name.to_owned() }
        }
    }
}

assert_eq!(Fruits::new("bread").name, "banana");
assert_eq!(Fruits::new("kiwi").name, "kiwi");

// Because the lookup is a `const fn`, it can be used with generic consts:

struct MyFruit<const C: char> {
    count: u64,
}

impl<const C: char> MyFruit<C> {
    const NAME: &'static str = match Fruits::get(C) {
        Some(s) => s,
        None => panic!("no fruit found"),
    };

    pub fn desc(&self) -> String {
        format!("{} {}", self.count, Self::NAME)
    }
}

let f = MyFruit::<'d'> { count: 42 };
assert_eq!(f.desc(), "42 durian");

No runtime deps