I have a struct with a constant generic parameter VAR
. This parameter is used in methods, improving the runtime speed, due to large amount of comparisons can be done compile time.
It's rather difficult to store and pass around a generic type everywhere. I have a fixed number of variants, I could list in an enum SquirrelVariant
, I can pass around easier, and use match
to branch out to generic functions.
Creating the enum from a Squirrel<VAR>
is rather difficult, rust doesn't seem to allow compile time match
or anything like that.
struct Squirrel<const VAR: u8>
{
}
enum SquirrelVariant
{
V1(Squirrel<1>),
V2(Squirrel<2>),
V3(Squirrel<3>),
}
// failed attempt 1)
fn make_squirrel_variant<const VAR: u8>(s: Squirrel<VAR>) -> SquirrelVariant
{
match VAR {
1 => SquirrelVariant::V1(s), // expected `1_u8`, found `VAR`
2 => SquirrelVariant::V2(s), // expected `2_u8`, found `VAR`
3 => SquirrelVariant::V3(s), // expected `3_u8`, found `VAR`
}
}
// failed attempt 2)
impl From<Squirrel<1>> for SquirrelVariant
{
fn from(s: Squirrel<1>) -> Self
{
SquirrelVariant::V1(s)
}
}
impl From<Squirrel<2>> for SquirrelVariant
{
fn from(s: Squirrel<2>) -> Self
{
SquirrelVariant::V2(s)
}
}
impl From<Squirrel<3>> for SquirrelVariant
{
fn from(s: Squirrel<3>) -> Self
{
SquirrelVariant::V3(s)
}
}
fn make_squirrel_variant2<const VAR: u8>(s: Squirrel<VAR>) -> SquirrelVariant
{
s.into() // the trait `From<Squirrel<VAR>>` is not implemented for `SquirrelVariant`
// = help: the following implementations were found:
// <SquirrelVariant as From<Squirrel<1_u8>>>
// <SquirrelVariant as From<Squirrel<2_u8>>>
// <SquirrelVariant as From<Squirrel<3_u8>>>
}
CodePudding user response:
You can use the following trick to resolve the type errors:
struct Squirrel<const VAR: u8> {}
impl<const VAR: u8> Squirrel<VAR> {
fn transmute_squirrel_type<const VAR2: u8>(self) -> Squirrel<VAR2> {
if VAR == VAR2 {
Squirrel { }
} else {
unreachable!()
}
}
}
enum SquirrelVariant
{
V1(Squirrel<1>),
V2(Squirrel<2>),
V3(Squirrel<3>),
}
impl<const VAR: u8> Squirrel<VAR> {
fn to_variant(self) -> SquirrelVariant {
match VAR {
1 => SquirrelVariant::V1(self.transmute_squirrel_type()),
2 => SquirrelVariant::V2(self.transmute_squirrel_type()),
3 => SquirrelVariant::V3(self.transmute_squirrel_type()),
_ => unreachable!()
}
}
}