Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I convert a string to enum without macros in Rust?

For example, if I have code like:

enum Foo {     Bar,     Baz,     Bat,     Quux }  impl Foo {     from(input: &str) -> Foo {         Foo::input     } } 

This will obviously fail because input is not a method of Foo. I can manually type:

from(input: &str) -> Foo {     match(input) {         "Bar" => Foo::Bar,         // and so on...     } } 

but I'm not getting the automatic convenience.

It looks like Java has a string lookup function on enums for this specific purpose.

Is it possible to get this without writing my own macro or importing one from a crate?

like image 743
bright-star Avatar asked Aug 22 '16 01:08

bright-star


People also ask

Can you convert string to enum?

IsDefined() method to check if a given string name or integer value is defined in a specified enumeration. Thus, the conversion of String to Enum can be implemented using the Enum. Parse ( ) and Enum.

How do you create an enum in Rust?

To declare an enumeration, we write the enum keyword, followed by a unique name and a code block. Inside the code block we declare our actual words that will map to numbers, separated by commas. Enums in Rust are conventionally written with pascal case.

How do you convert enum to string in Rust?

The easiest way to convert an enum to a String in Rust is to implement the std::fmt::Display trait. Then you can call the to_string() method.

How do you match a string to an enum?

For comparing String to Enum type you should convert enum to string and then compare them. For that you can use toString() method or name() method. toString()- Returns the name of this enum constant, as contained in the declaration.


2 Answers

You should implement std::str::FromStr trait.

use std::str::FromStr;  #[derive(Debug, PartialEq)] enum Foo {     Bar,     Baz,     Bat,     Quux, }  impl FromStr for Foo {      type Err = ();      fn from_str(input: &str) -> Result<Foo, Self::Err> {         match input {             "Bar"  => Ok(Foo::Bar),             "Baz"  => Ok(Foo::Baz),             "Bat"  => Ok(Foo::Bat),             "Quux" => Ok(Foo::Quux),             _      => Err(()),         }     } }    fn main() {     // Use it like this     let f = Foo::from_str("Baz").unwrap();     assert_eq!(f, Foo::Baz); } 

Code-generation (aka automatic convenience) and reflections usually bear a cost. In practice, it is unlikely that you will end up with more than a few enum variants.

Run in the playground

like image 171
Pandemonium Avatar answered Oct 13 '22 20:10

Pandemonium


Edit: The answer is no. Rust does not provide reflection and usually use #[derive] for that kind of tasks.

You can use the crates enum_derive and custom_derive to do what you want.

Here is an exemple:

#[macro_use] extern crate custom_derive; #[macro_use] extern crate enum_derive;  custom_derive! {     #[derive(Debug, EnumFromStr)]     enum Foo {         Bar,         Baz,         Bat,         Quux     } }  fn main() {     let variable: Foo = "Bar".parse().unwrap();     println!("{:?}", variable); } 

the derive of the custom EnumFromStr allows you to use the parse method to get a Foo.

like image 43
antoyo Avatar answered Oct 13 '22 19:10

antoyo