Is there a simple way to create an enum
that provides the ability to coerce or otherwise cast instances from one variant to another, as long as the underlying types match?
For instance, given this enum:
enum CanConvert {
Vec1(Vec<String>),
Vec2(Vec<String>),
NotVec(i32),
}
I would like to be able to easily convert between the Vec1
and Vec2
variants:
let v1 = CanConvert::Vec1(["one", "two", "three", "uno", "dos", "tres"]
.iter()
.map(|&s| s.into())
.collect());
let v2 = v1 as CanConvert::Vec2;
The code above currently gives the error not a type
, since enum variants are not (currently) considered types. And even if it compiled, it's not clear how the case where v1
is the NotVec
variant should be handled (panic?).
This works, but it's pretty verbose, and this seems like it should be a reasonably common pattern:
let v2 = match v1 {
CanConvert::Vec1(ref underlying) |
CanConvert::Vec2(ref underlying) => CanConvert::Vec2(underlying.clone()),
_ => panic!("v1 did not have appropriate underlying type!"),
};
So is there a simple way to provide this kind of simple type-transformation between variants where possible? I haven't written any of my own Deref
coercions, but that seems like it might be what I'm looking for here. (A coercion wrapped in some kind of custom derive
would be ideal.)
EDIT: Note that as far as I can tell, there cannot be any safe way of obtaining a reference to the original, with the desired variant type; a full clone is required, because the reference would necessarily have the wrong variant tag. However, it seems like it should be possible to convert the original enum
by simply changing the tag appropriately.
var as NewType
explicit? – Kyle Strand