Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert a string to an enum?

My original approach was to create method called to_str() which will return a slice, but I am not sure that it is correct approach because this code doesn't compile.

enum WSType {
    ACK,
    REQUEST,
    RESPONSE,
}

impl WSType {
    fn to_str(&self) -> &str {
        match self {
            ACK => "ACK",
            REQUEST => "REQUEST",
            RESPONSE => "RESPONSE",            
        }
    }
}

fn main() {
    let val = "ACK";
    // test
    match val {
        ACK.to_str() => println!("ack"),
        REQUEST.to_str() => println!("ack"),
        RESPONSE.to_str() => println!("ack"),
        _ => println!("unexpected"),
    }
}
like image 925
Sergey Avatar asked Apr 08 '16 20:04

Sergey


People also ask

How do I create an enum from a string?

You can create Enum from String by using Enum. valueOf() method. valueOf() is a static method that is added on every Enum class during compile-time and it's implicitly available to all Enum along with values(), name(), and cardinal() methods.

Can we convert string to enum in Java?

The valueOf() method of the Enum class in java accepts a String value and returns an enum constant of the specified type.

How do I convert string to enum in Python?

To convert a string to an enum in Python:Import the Enum class from the enum module. Declare an enum by extending the Enum class. Assign class properties on the enum class.

Can we store string in enum?

Enum constants can only be of ordinal types ( int by default), so you can't have string constants in enums.


1 Answers

The correct thing is to implement FromStr. Here, I'm matching against the string literals that represent each enum variant:

#[derive(Debug)]
enum WSType {
    Ack,
    Request,
    Response,
}

impl std::str::FromStr for WSType {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "ACK" => Ok(WSType::Ack),
            "REQUEST" => Ok(WSType::Request),
            "RESPONSE" => Ok(WSType::Response),
            _ => Err(format!("'{}' is not a valid value for WSType", s)),
        }
    }
}

fn main() {
    let as_enum: WSType = "ACK".parse().unwrap();
    println!("{:?}", as_enum);

    let as_enum: WSType = "UNKNOWN".parse().unwrap();
    println!("{:?}", as_enum);
}

To print a value, implement Display or Debug (I've derived Debug here). Implementing Display also gives you .to_string().


In certain cases, there are crates that can reduce some of the tedium of this type of conversion. strum is one such crate:

use strum_macros::EnumString;

#[derive(Debug, EnumString)]
#[strum(serialize_all = "shouty_snake_case")]
enum WSType {
    Ack,
    Request,
    Response,
}
like image 112
Shepmaster Avatar answered Oct 19 '22 18:10

Shepmaster