简体   繁体   中英

Create enum of generic variants of a type

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>>>
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=54ec536a9d84d13b4b3ae16180022ba8

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM