Rustlings: enums3.rs #Issue34 — Enums in Rust
Rustlings Challenge: enums3.rs Solution Walkthrough

This is the thirty-fourth (34th) issue of the Rustlings series. In this issue, we provide solutions to Rustlings exercises along with detailed explanations. In this issue we will solve the challenge on enums3.rs.
Previous challenge #Issue 33
Rust allows you to define types called “enums” which enumerate possible values. Enums are a feature in many languages, but their capabilities differ in each language. Rust’s enums are most similar to algebraic data types in functional languages, such as F#, OCaml, and Haskell. Useful in combination with enums is Rust’s “pattern matching” facility, which makes it easy to run different code for different values of an enumeration.
Challenge:
// enums3.rs
//
// Address all the TODOs to make the tests pass!
//
// Execute `rustlings hint enums3` or use the `hint` watch subcommand for a
// hint.
// I AM NOT DONE
enum Message {
// TODO: implement the message variant types based on their usage below
}
struct Point {
x: u8,
y: u8,
}
struct State {
color: (u8, u8, u8),
position: Point,
quit: bool,
message: String,
}
impl State {
fn change_color(&mut self, color: (u8, u8, u8)) {
self.color = color;
}
fn quit(&mut self) {
self.quit = true;
}
fn echo(&mut self, s: String) {
self.message = s
}
fn move_position(&mut self, p: Point) {
self.position = p;
}
fn process(&mut self, message: Message) {
// TODO: create a match expression to process the different message variants
// Remember: When passing a tuple as a function argument, you'll need extra parentheses:
// fn function((t, u, p, l, e))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_match_message_call() {
let mut state = State {
quit: false,
position: Point { x: 0, y: 0 },
color: (0, 0, 0),
message: "hello world".to_string(),
};
state.process(Message::ChangeColor(255, 0, 255));
state.process(Message::Echo(String::from("Hello world!")));
state.process(Message::Move(Point { x: 10, y: 15 }));
state.process(Message::Quit);
assert_eq!(state.color, (255, 0, 255));
assert_eq!(state.position.x, 10);
assert_eq!(state.position.y, 15);
assert_eq!(state.quit, true);
assert_eq!(state.message, "Hello world!");
}
}If you run the code on your editor, the compiler will throw the error:
warning: methods `change_color`, `quit`, `echo`, `move_position`, and `process` are never used
--> src/lib.rs:27:8
|
26 | impl State {
| ---------- methods in this implementation
27 | fn change_color(&mut self, color: (u8, u8, u8)) {
| ^^^^^^^^^^^^
...
31 | fn quit(&mut self) {
| ^^^^
...
35 | fn echo(&mut self, s: String) {
| ^^^^
...
39 | fn move_position(&mut self, p: Point) {
| ^^^^^^^^^^^^^
...
43 | fn process(&mut self, message: Message) {
| ^^^^^^^
warning: `playground` (lib) generated 5 warnings (run `cargo fix --lib -p playground` to apply 1 suggestion)
error[E0599]: no variant or associated item named `ChangeColor` found for enum `Message` in the current scope
--> src/lib.rs:62:32
|
10 | enum Message {
| ------------ variant or associated item `ChangeColor` not found for this enum
...
62 | state.process(Message::ChangeColor(255, 0, 255));
| ^^^^^^^^^^^ variant or associated item not found in `Message`
error[E0599]: no variant or associated item named `Echo` found for enum `Message` in the current scope
--> src/lib.rs:63:32Explanation:
In the challenge, we are required to define an enum called Message with several variants: ChangeColor, Echo, Move, and Quit. These variants represent different types of messages that can be processed.
We are also needed to implement a State struct, which contains various fields, including color, position, a quit flag, and a message. The State struct is used to keep track of the state of a system.
The main task is to implement the process method for the State struct, which takes a Message as an argument and uses pattern matching (match) to handle each variant of the message appropriately. For example, if the message is ChangeColor, it should call the change_color method, and so on.
Solution:
enum Message {
// TODO: implement the message variant types based on their usage below
ChangeColor(u8, u8, u8),
Echo(String),
Move(Point),
Quit,
}
struct Point {
x: u8,
y: u8,
}
struct State {
color: (u8, u8, u8),
position: Point,
quit: bool,
message: String,
}
impl State {
fn change_color(&mut self, color: (u8, u8, u8)) {
self.color = color;
}
fn quit(&mut self) {
self.quit = true;
}
fn echo(&mut self, s: String) {
self.message = s
}
fn move_position(&mut self, p: Point) {
self.position = p;
}
fn process(&mut self, message: Message) {
// TODO: create a match expression to process the different message variants
// Remember: When passing a tuple as a function argument, you'll need extra parentheses:
// fn function((t, u, p, l, e))
match message {
Message::ChangeColor(r,g,b) => self.change_color((r,g,b)),
Message::Echo(str) => self.echo(str),
Message::Move(ptr) => self.move_position(ptr),
Message::Quit => self.quit(),
}
}
}You can experiment with the code on Rust Playground.
Resources
Before you go
Thank you for taking the time to read through this challenge. We invite you to share your knowledge of Rust as well. If you found this article valuable, please don’t hesitate to share it with others. Don’t forget to follow the publication and give the article some claps 👏.
Thank you, and we look forward to seeing you for the next challenges!






