-2

I have an enum with a String:

enum MyLovelyEnum {
    Thing(String),
}

For tests, I would like to be able to pass in a &'static str to avoid MyLovelyEnum::Thing("abc".to_string) over and over.

I found that you can do this nicely with structs with a constructor:

// From: https://hermanradtke.com/2015/05/06/creating-a-rust-function-that-accepts-string-or-str.html
struct Person {
    name: String,
}

impl Person {
    fn new<S: Into<String>>(name: S) -> Person {
        Person { name: name.into() }
    }
}

fn main() {
    let person = Person::new("Herman");
    let person = Person::new("Herman".to_string());
}

I know I can use lifetimes or Cow as described in What's the best practice for str/String values in Rust enums? or I can make my own function.

Is there something close to the example in the blog post for enums? e.g.

// this is the kind of thing I am after but this specifically is not correct syntax
enum MyLovelyEnum {
  Thing<S: Into<String>>(S)
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
John
  • 65
  • 5
  • Why don't you want to do _exactly_ what the blog post does and make a constructor for your enum? – Shepmaster Dec 15 '21 at 15:46
  • As I said I know I can do that, I wonder if something like: I have an enum with a String: ``` enum MyLovelyEnum { Thing>(S), } ``` is possible? – John Dec 15 '21 at 15:48
  • That's not "like the blog post" though. The blog post creates a constructor associated function. Why don't you want to create one for your enum? – Shepmaster Dec 15 '21 at 15:50
  • I apologize for sounding hostile; that's not my intention. I simply don't understand the problem, so I'm asking. You have a solution that **you** state "can do this nicely", so I don't follow why you don't want to use it. Your post doesn't explain what's **wrong** with creating a constructor, either. You ask "Is there something close to the example in the blog post for enums?". You appear to already know that you can create a constructor for the enum, so I don't see how we'd get from what is in the post to anywhere else, so I ask questions. – Shepmaster Dec 15 '21 at 15:59
  • I want to know specifically if you can declare an Enum value that takes a String or &str without needing additional functions. Taking the blog's example I have tried: ``` enum MyLovelyEnum { Thing>(S) } ``` Which is not valid. I don't know Rust well enough to say if my attempt at the syntax is wrong but it is possible, or if it's fundamentally impossible. I suspect the later – John Dec 15 '21 at 16:00
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240177/discussion-between-shepmaster-and-john). – Shepmaster Dec 15 '21 at 16:02
  • BTW, if you don't need an owned string, you can use `&str` and `AsRef` instead of `String` and `Into`. – Chayim Friedman Dec 15 '21 at 17:04

1 Answers1

2

You can create a generic enum:

enum MyLovelyEnum<S>
where
    S: Into<String>,
{
    Thing(S),
}

MyLovelyEnum::Thing("a");
MyLovelyEnum::Thing("b".to_string());

I likely wouldn't do that in my code, instead opting to create a constructor, much like the blog post you linked:

enum MyLovelyEnum {
    Thing(String),
}

impl MyLovelyEnum {
    fn thing(s: impl Into<String>) -> Self {
        MyLovelyEnum::Thing(s.into())
    }
}

MyLovelyEnum::thing("a");
MyLovelyEnum::thing("b".to_string());
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I would add that with the first approach, _every_ function using this enum will have to call `.into()`, meaning you'll carry the overhead of converting to `String` every time you call a function, which is usually not what you want. – Chayim Friedman Dec 15 '21 at 17:04
  • @ChayimFriedman while the spirit of your comment is true, I'd point out that you can take the `MyLovelyEnum` and convert it into a `MyLovelyEnum` and then pass it down into the rest of your program. Then only the "outer crust" of your API has to deal with the flexibility, the rest can assume a fixed `String`. – Shepmaster Dec 15 '21 at 19:51
  • Yes, I meant the API, not the internal details. – Chayim Friedman Dec 15 '21 at 21:50