rtviii
rtviii

Reputation: 897

Correct way to "compose" enums in Rust

I'd like to be able to have a sum type that is either of two enums' members but am not sure if I'm doing this correctly. The idea would be for Token to be either a Coordinate or AA and for the process_line to return an array of Tokens. Pretty basic. But do I have to wrap a Token(...) around every Coordinate or AA that I initialize for them to be such?

struct Coordinate {
    x: f64,
    y: f64,
    z: f64
}

enum AminoAcid {
    VAL, GLN ,ARG,
    LEU, THR ,TYR,
    SER, PRO ,CYS,
    GLY, ALA ,MET
}

enum Token {
    Coordinate(Coordinate),
    AminoAcid(AminoAcid)
}

// Want a function that returns a list of legal tokens given a &line.
fn _process_line(line:&str)->Vec<Token>{
    let token = Token::AminoAcid(AminoAcid::ARG);
    return vec![token];
}

For example, in typescript I could do

type A = "Fur" | "Silver" | "Glass"
type B = "Leather" | "Wood"  | "Bronze"
type Material  = A | B;

var x: Material = "Wood" // is okay

whereas here I am having to do the whole Material("Wood") type of thing with

let token = Token::AminoAcid(AminoAcid::ARG);
let token = AminoAcid::ARG; // it would have been great to just have this, is this possible?

Upvotes: 2

Views: 923

Answers (1)

Netwave
Netwave

Reputation: 42718

You can implement From for each inner type. By implementing it you can call Into::into on your inner types instances to get the outter enum representation:

struct Coordinate{
    x:f64,    y:f64,    z:f64
}

enum AminoAcid {
    VAL, GLN ,ARG,
    LEU, THR ,TYR,
    SER, PRO ,CYS,
    GLY, ALA ,MET
}

enum Token {
    Coordinate(Coordinate),
    AminoAcid(AminoAcid)
}

impl From<Coordinate> for Token {
    fn from(coord: Coordinate) -> Self {
        Self::Coordinate(coord)
    }
}

impl From<AminoAcid> for Token {
    fn from(aminoacid: AminoAcid) -> Self {
        Self::AminoAcid(aminoacid)
    }
}

// Want a function that returns a list of legal tokens given a &line.
fn _process_line(line:&str)->Vec<Token>{
    return vec![AminoAcid::ARG.into()];
}

Playground

Upvotes: 6

Related Questions