将枚举转换为BTreeMap?

时间:2015-02-01 05:50:33

标签: rust

我可以将枚举转换为TreeMap吗?

enum En1 {
  val1, 
  val2, 
  val3
}

fn fn1() -> BTreeMap<String, En1> {
  let mut map = BTreeMap::new();
   //iterate through En1 somehow

   // now map is: "val1" -> val1, "val2" -> val2, "val3" -> val3
   map
}

我的意思是,最简单的方法,DRY。

1 个答案:

答案 0 :(得分:1)

编辑:实际上,这是一个更好的版本,应该更加高效和通用。另外,您可以将宏重用于其他枚举(playpen link)。

#![feature(core)] // IO is currently in flux.

use std::collections::BTreeMap;

macro_rules! symbolic_enum {
    ($enum_name:ident { $($variant:ident,)* }) => {
        #[derive(Copy, Clone, Debug)]
        enum $enum_name {
            $($variant,)*
        }

        impl $enum_name {
            pub fn values() -> &'static /*'*/ [$enum_name] {
                use self::$enum_name::*;
                const VALUES: &'static /*'*/ [$enum_name] = &[$($variant),*];
                VALUES
            }

            pub fn names() -> &'static /*'*/ [&'static /*'*/ str] {
                const NAMES: &'static /*'*/ [&'static /*'*/ str] = &[$(stringify!($variant)),*];
                NAMES
            }

            pub fn items() -> &'static /*'*/ [(&'static /*'*/ str, $enum_name)] {
                use self::$enum_name::*;
                const ITEMS: &'static /*'*/ [(&'static /*'*/ str, $enum_name)] = &[
                    $((stringify!($variant), $variant)),*
                ];
                ITEMS
            }
        }
    }
}

symbolic_enum! {
    En1 {
        Val1,
        Val2,
        Val3,
    }
}

fn main() {
    println!("{:?}", En1::values());
    println!("{:?}", En1::names());
    println!("{:?}", En1::items());
    let map: BTreeMap<_, _> = En1::items().iter().cloned().collect();
    println!("{:?}", map);
}

原创:这是我能想到的最短(playpen link):

#![feature(core)] // IO is currently in flux.

use std::collections::BTreeMap;

#[derive(Copy, Clone, Debug)]
enum En1 {
    Val1, 
    Val2, 
    Val3,
}

// /*'*/ is to fix syntax highlighting
const EN1_VALUES: &'static /*'*/ [En1] = &[En1::Val1, En1::Val2, En1::Val3];

impl En1 {
    pub fn values() -> &'static /*'*/ [En1] {
        EN1_VALUES
    }

    pub fn as_map() -> BTreeMap<String, En1> {
        En1::values().iter().cloned().map(|e| (format!("{:?}", e), e)).collect()
    }
}

fn main() {
    println!("{:?}", En1::as_map());
}