We can have multiple variants types in single enum.
In this task we need to write 5 variants.
enum Message {
Resize { width: i32, height: i32 }, // with named field data like a struct
Move(Point), // has a struct data
Echo(String), // has a single String data
ChangeColor(i32, i32, i32), // has 3 data like a tuple
Quit, // no data
}
enums3.rs
struct Point {
x: u64,
y: u64,
}
enum Message {
Resize { width: u64, height: u64 },
Move(Point),
Echo(String),
ChangeColor(u8, u8, u8),
Quit,
}
struct State {
width: u64,
height: u64,
position: Point,
message: String,
// RGB color composed of red, green and blue.
color: (u8, u8, u8),
quit: bool,
}
impl State {
fn resize(&mut self, width: u64, height: u64) {
self.width = width;
self.height = height;
}
fn move_position(&mut self, point: Point) {
self.position = point;
}
fn echo(&mut self, s: String) {
self.message = s;
}
fn change_color(&mut self, red: u8, green: u8, blue: u8) {
self.color = (red, green, blue);
}
fn quit(&mut self) {
self.quit = true;
}
fn process(&mut self, message: Message) {
// TODO: Create a match expression to process the different message
// variants using the methods defined above.
match message {
Message::Resize {
width: w,
height: h,
} => self.resize(w, h),
Message::Move(p) => self.move_position(p),
Message::Echo(s) => self.echo(s),
Message::ChangeColor(r, g, b) => self.change_color(r, g, b),
Message::Quit => self.quit(),
}
}
}
fn main() {
// You can optionally experiment here.
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_match_message_call() {
let mut state = State {
width: 0,
height: 0,
position: Point { x: 0, y: 0 },
message: String::from("hello world"),
color: (0, 0, 0),
quit: false,
};
state.process(Message::Resize {
width: 10,
height: 30,
});
state.process(Message::Move(Point { x: 10, y: 15 }));
state.process(Message::Echo(String::from("Hello world!")));
state.process(Message::ChangeColor(255, 0, 255));
state.process(Message::Quit);
assert_eq!(state.width, 10);
assert_eq!(state.height, 30);
assert_eq!(state.position.x, 10);
assert_eq!(state.position.y, 15);
assert_eq!(state.message, "Hello world!");
assert_eq!(state.color, (255, 0, 255));
assert!(state.quit);
}
}
In this exercise we need to create matching pattern syntax for all the available variants in Message enum and call it's respective method.
For each variants that have data, we want to catch or get that data so we can use it as arguments when calling it's respective method.
match message {
// bind width -> w and height -> h
Message::Resize { width: w, height: h } => self.resize(w, h),
// bind Point -> p
Message::Move(p) => self.move_position(p),
// bind String -> s
Message::Echo(s) => self.echo(s),
// bind first value -> r
// bind second value -> r
// bind third value -> r
Message::ChangeColor(r, g, b) => self.change_color(r, g, b),
Message::Quit => self.quit(),
}
This pattern syntax will bind data in the message enum variants into the defined variables.