Variable assignment in a match

Hello,

I'm new to Rust and come from the PHP world so I'm having a bit of a hard time figuring it all out.
I'm trying to do a match on a string (it works) and assign to a variable an object of type termion::color but as I'm changing color it doesn't work...as soon as I do the first assignment, rust expects me to assign the same object to this variable.

    let color_choice = match &*data_color.color { 
        "Red" => color::Red,
        "Blue" => color::Blue,
        "Yellow" => color::Yellow,
        "Green" => color::Green,                 
        _ => color::White,
    };

The error :

27 |       let mut color_choice = match &*data_color.color { 
   |  ____________________________-
28 | |         "Red" => color::Red,
   | |                  ---------- this is found to be of type `Red`
29 | |         "Blue" => color::Blue,
   | |                   ^^^^^^^^^^^ expected struct `Red`, found struct `Blue`
30 | |         "Yellow" => color::Yellow,
31 | |         "Green" => color::Green,                 
32 | |         _ => color::White,
33 | |     };
   | |_____- `match` arms have incompatible types

How can I do this?

Or do you have an easier way to be able to use a different color directly without going through a match?
Here is my fonction :

struct DataColor { 
    color: String,
    bold: bool,
    args: Vec<String>,
}
fn print_with_color(data_color: DataColor) {
    let color_choice = match &*data_color.color { 
        "Red" => color::Red,
        "Blue" => color::Blue,
        "Yellow" => color::Yellow,
        "Green" => color::Green,                 
        _ => color::White,
    };
    for text in &data_color.args {
        if data_color.bold {
            println!("{}{}{}", color::Fg(color_choice), style::Bold, text);
        } else { 
            println!("{}{}", color::Fg(color_choice), text);    
        }
    }
}

As I don't know how I can pass the termion::color object directly to my function (color: String need to be a color::XX), I therefore pass through a string of the type "Red", "Green"... and then via the match I thought of assigning it to a variable the right color.

Thanks in advance and sorry for his amateurish questions.

Those colors are structs of differents type. To solve your immediate issue you can wrap them in your own enum :

enum Color {
    Red(termion::color::Red),
    Green(termion::color::Green),
    Blue(termion::color::Blue),
    ...
}

Or Box the values using the Color trait :

let color_choice: Box<dyn color::Color> = match &*data_color.color { 
    "Red" => Box::new(color::Red),
    ...
};
3 Likes

Looking at the implementations of the relevant trait, it looks like you could work well with &'static dyn Color in this case.

Try something like

    let color_choice: &dyn Color = match &*data_color.color { 
        "Red" => &color::Red,
        "Blue" => &color::Blue,
        "Yellow" => &color::Yellow,
        "Green" => &color::Green,                 
        _ => &color::White,
    };

(you might need to import that trait, use termion::color::Color;)

2 Likes

Thanks you. It's ok now

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.