If I have a type like MyEnum
, how can I map it in cases where not every variant is parameterized?
For example, I\'d like to convert from
Some languages (like C++), use Duck Typing: if it quacks like a duck, it must be a duck, and therefore names matter. Rust does not.
In Rust, names are just some display utility for us mere humans, the B
in MyEnum<u32>
and MyEnum<String>
may happen to have the same visual representation, but they are completely different syntactic entities as far as the language is concerned.
There are multiple ways to alleviate your pain, though:
build.rs
script can be used as wellI'll show-case the latter:
enum MyEnumImpl {
A,
B,
C,
}
enum MyEnum<T> {
Independent(MyEnumImpl),
Dependent(T),
}
Obviously, the latter makes it much easier to manually map things.
macro_rules! partial_enum {
($name: ident, $some: ident, $($none: ident),+) => {
#[derive(Debug)]
enum $name<T> {
$some(T),
$($none),+
}
impl<T> $name<T> {
fn convert<U>(self) -> Result<$name<U>, T> {
match self {
$name::$some(x) => Err(x),
$($name::$none => Ok($name::$none)),+
}
}
}
}
}
partial_enum!(MyEnum, D, B, C);
fn trans(a: MyEnum<u32>) -> MyEnum<String> {
let a_split: Result<MyEnum<String>, u32> = a.convert();
match a_split {
Ok(is_none) => is_none,
Err(not_none) => MyEnum::D(not_none.to_string()),
}
}
fn main() {
println!("{:?}", trans(MyEnum::D(13)));
}
I'd create a map
method on your enum:
#[derive(Debug)]
enum MyEnum<T> {
B,
C,
D(T),
}
impl<T> MyEnum<T> {
fn map<U>(self, f: impl FnOnce(T) -> U) -> MyEnum<U> {
use MyEnum::*;
match self {
B => B,
C => C,
D(x) => D(f(x)),
}
}
}
fn main() {
let answer = MyEnum::D(42);
let answer2 = answer.map(|x| x.to_string());
println!("{:?}", answer2);
}
This is similar to existing map
methods, such as Option::map.
Well, this is actually an answer:
enum MyEnum<T> {
B,
C,
D(T),
}
fn trans(a: MyEnum<u32>) -> MyEnum<String> {
match a {
MyEnum::D(i) => MyEnum::D(i.to_string()),
MyEnum::B => MyEnum::B,
MyEnum::C => MyEnum::C
}
}
fn main() {
}
But repeating all variants isn't acceptable when there's a lot of them..