Kalanamith
Kalanamith

Reputation: 20648

How to read a value of an enum which associates with a custom type in Rust?

I have an implementation in Rust as follows. In the main function, I am reading a value in SalaryRange enum and this will display High("So High").

// This can be a complex type, just using string for the question 
type SRange = String;
type SalEnu = SalaryRange<SRange>;

struct User<SRange> {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
    income: Income<SRange>,
}

struct Income<SRange> {
    salary_range: SalaryRange<SRange>
}

#[derive(Debug)]
enum SalaryRange<SRange> {
    Low(SRange),
    Mid(SRange),
    High(SRange),
}

fn main() {
    let user1 = User {
        email: String::from("[email protected]"),
        username: String::from("test_name"),
        active: true,
        sign_in_count: 1,
        income: Income {
            salary_range: (
                SalaryRange::High("So High")
            )
        },
    };
    let mut srange: SalaryRange<&str> = user1.income.salary_range;
    println!("{:?}", srange);
}

Link for this example can be found here.

Just wanted to know if there is a possibility to read and print the value in that enum as println!("{:?}", srange::High);, just to print out the string value? I only want to print the value So High.

If I use srange::High This will throw an error saying

      println!("{:?}", srange::High);
|                      ^^^^^^ use of undeclared type or module `srange`
error: aborting due to previous error

Upvotes: 2

Views: 461

Answers (3)

DrLarck
DrLarck

Reputation: 374

I know it's been a while since the question has been opened, but I would like to complete Peter's answer.

There is a more idiomatic way to achieve what you want. Just implement the std::fmt::Display trait to your enum as following:

pub enum SalaryRange {
    LOW(String),
    MID(String),
    HIGH(String),
}

impl std::fmt::Display for SalaryRange {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let content = match self {
            SalaryRange::LOW(content) => content,
            SalaryRange::MID(content) => content,
            SalaryRange::HIGH(content) => content,
        };

        write!(f, "{}", content)
    }
}

The std::fmt::Display trait allows you to display the content held by your enum value like this:

let salary_range = SalaryRange::HIGH("So high".to_string());
println!("{}", salary_range);
// outputs: "So high"

This should work with any type.

Playground to test it: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=eaea33a955dc9dcd81a4b96ec22d82bd

Upvotes: 0

Peter Hall
Peter Hall

Reputation: 58695

You can implement a method on your enum to extract the value:

#[derive(Debug)]
enum SalaryRange<S> {
    Low(S),
    Mid(S),
    High(S),
}

impl<S> SalaryRange<S> {
    fn value(&self) -> &S {
        match self {
            SalaryRange::Low(value) => value,
            SalaryRange::Mid(value) => value,
            SalaryRange::High(value) => value,
        }
    }
}
println!("{:?}", srange.value());

Upvotes: 3

hellow
hellow

Reputation: 13410

You can pattern match srange with the if let syntax.

if let SalaryRange::High(s) = srange {
    println!("{}", s);
}

will print "so high".

Upvotes: 3

Related Questions