I have a trait Foo, with some implementations, together with an enum Foos with one variant per implemention. I want to be able to convert my enum into Box<dyn Foo>.
This is my current solution:
trait Foo {}
struct FooA {}
impl Foo for FooA {}
struct FooB {}
impl Foo for FooB {}
struct FooC {}
impl Foo for FooC {}
enum Foos {
A(FooA),
B(FooB),
C(FooC),
}
impl Foos {
fn into_box(self) -> Box<dyn Foo> {
match self {
Foos::A(foo) => Box::new(foo),
Foos::B(foo) => Box::new(foo),
Foos::C(foo) => Box::new(foo),
}
}
}
It works, but there's a lot of boiler plate in into_enum. As the number of variants grow, so will the function. Is there a simpler way to do this? It feels like it should be a one liner!
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.
In Rust, methods cannot only be defined on structs, they can also be defined on tuples and enums, and even on built-in types like integers.
The enum keyword allows the creation of a type which may be one of a few different variants. Any variant which is valid as a struct is also valid as an enum .
To initialize an enum with values, we assign the enum with a value to a variable. We write the enum name, followed by double colon operators and the enum value name. Lastly, we specify a value between parentheses. In the example above, we assign 1 to Enabled and 0 to Disabled in the variables yes and no.
With the enum_dispatch crate, you can write
#[macro_use]
extern crate enum_dispatch;
#[enum_dispatch]
trait Foo {}
struct FooA {}
impl Foo for FooA {}
struct FooB {}
impl Foo for FooB {}
struct FooC {}
impl Foo for FooC {}
#[enum_dispatch(Foo)]
enum Foos {
A(FooA),
B(FooB),
C(FooC),
}
to get a generated impl Foo for Foos. You can then convert Foos to Box<dyn Foo> with simply Box::new.
There is a potential downside to this approach: Box::new(Foos::A(FooA)) contains a Foos, not an FooA, so it will incur the overhead of both the dynamic dispatch from dyn Foo to Foos and the enum dispatch from Foos to FooA.
On the other hand, now that you have impl Foo for Foos: everywhere you would have used Box<dyn Foo>, you’ll instead be able to directly use Foos, which should be more efficient in every way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With