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!()
}
}
}
