ruststructenums

How to declare a variant of a rust enum with a pre-existing variant outside of the enum?


I have code analogous to the following:

struct A(String);
impl A {
    fn new(&str) -> Self
    ...

}

struct B(String);
impl B {
    fn new(&str) -> Self
    ...

}

struct C(String);
impl C {
    fn new(&str) -> Self
    ...

}

enum AorB {
    A(A),
    B(B),
}

enum BorC {
    B(B),
    C(C),
}

fn main() {
    let this = B.new("Hello Solar System");
    let that = AorB(this) // This is the line I'm currently having difficulty with.
    let these = BorC(this::B)// And then ideally make a copy of a B variant of AorB turned into a BorC variant
}

So far, I'm stuck on the first part. I've tried casting like with a struct AorB {this}; and AorB::A.new(this) isn't an option because it's a String by this point, as new() is transformative.

I just need to wrap "A" in the "AorB" enum, but I can't quite figure out how to make it happen. And the examples in the rust book set enums initially, I've yet to see how to pull a variable into the enum after creation.


Solution

  • to instantiate a new instance you need to use AorB::A(/*...*/).

    if you want some syntax sugar, you can implement Into<AorB> so that you can use the .into() function.

    for converting from AorB to BorC, you need to explictly match and convert it, because what if you are trying to convert a AorB::A variant to BorC, it doesn't map well, you need to let the program know what to do.

    you can impl TryFrom<AorB> for BorC this allow you to use the .try_into() function with a fallable convertion in case conversion fails

    pub struct A(String);
    pub struct B(String);
    pub struct C(String);
    
    enum AorB {
        A(A),
        B(B),
    }
    
    impl Into<AorB> for A {
        fn into(self) -> AorB {
            AorB::A(self)
        }
    }
    
    enum BorC {
        B(B),
        C(C),
    }
    
    impl TryFrom<AorB> for BorC {
        type Error = String;
        fn try_from(value: AorB) -> Result<Self, Self::Error> {
            match value {
                AorB::A(a) => Err("unexpected variant".to_string()),
                AorB::B(b) => Ok(BorC::B(b)),
            }
        }
    }
    
    fn main() {
        let this: A = A("Hello".to_string());
        let that: AorB = AorB::A(this);
    
        let this: A = A("Hello".to_string());
        let that: AorB = this.into();
    
        let these: BorC = that.try_into().unwrap();
    }