2016-12-21 4 views
2

D-Bus経由でNetworkManagerとやりとりするコードを書いています。enumをキー値のようなスキームとして使用したいと考えています。Rustのenumを双方向ルックアップテーブルとして使用する

例えば、私はこのenumの文字列Unknownを使用するように数字のゼロとして値0を使用し、異なるコンテキストにするために一度たい:

pub enum NetworkManagerState { 
    Unknown = 0, 
    Asleep = 10, 
    Disconnected = 20, 
    Disconnecting = 30, 
    Connecting = 40, 
    ConnectedLocal = 50, 
    ConnectedSite = 60, 
    ConnectedGlobal = 70, 
} 

そうするのきれいな、最も慣用的な方法は何ですか?それぞれのエントリが(ConnectedSite, 60u32, "Connected")のように見えるタプルベースの列挙型を定義し、各タプル属性をコンテキストに使用する方法はありますか?

+1

マクロが必要です。 – Shepmaster

+0

私は錆のユーザーではありませんが、慣用的な錆は文字列の値を避けることを好んでいます(パフォーマンス上の理由から)最初に遭遇したときに文字列値を解析し、その後のすべての処理に対応する列挙値を使用する方法はありませんか? – Dai

答えて

5
  1. enumをint型にキャストするには、as i32を使用できます。トレイトから使用して

    #[macro_use] 
    extern crate enum_primitive; 
    use enum_primitive::FromPrimitive; 
    
    enum_from_primitive! { 
    #[derive(Debug, PartialEq)] 
    pub enum NetworkManagerState { 
        Unknown = 0, 
        Asleep = 10, 
        Disconnected = 20, 
        Disconnecting = 30, 
        Connecting = 40, 
        ConnectedLocal = 50, 
        ConnectedSite = 60, 
        ConnectedGlobal = 70, 
    } 
    } 
    
    impl From<i32> for NetworkManagerState { 
        fn from(val: i32) -> NetworkManagerState { 
         NetworkManagerState::from_i32(val).expect("passed Value does not match an enum value!") 
        } 
    } 
    impl From<NetworkManagerState> for i32 { 
        fn from(val: NetworkManagerState) -> i32 { 
         val as i32 
        } 
    } 
    
    
    fn main() { 
        let value_i32 = 40; 
        let value_enum = NetworkManagerState::Connecting; 
    
        // enum to i32 
        println!("{:?}", value_enum as i32); 
    
        // i32 to enum 
        println!("{:?}", NetworkManagerState::from_i32(value_i32).unwrap()); 
    
        // using from trait 
        let y: i32 = NetworkManagerState::Connecting.into(); 
        println!("{:?}", y); 
    
        // using from trait 
        let x: NetworkManagerState = 40.into(); 
        println!("{:?}", x); 
    } 
    

cargo.toml:

[dependencies] 
enum_primitive = "*" 

main.rs

  • あなたがenum_primitiveクレートを使用することができ、あなたの列挙型にI32をキャストするには列挙型に変換できるすべての関数を関数に受け入れるようにすることができます:

    fn fancy_function<T: Into<NetworkManagerState>>(value: T) { 
        let internal: NetworkManagerState = value.into(); 
        println!("{:?}", internal); 
    } 
    
    ... 
    
    fancy_function(60); 
    fancy_function(NetworkManagerState::Asleep); 
    
  • 関連する問題