diff --git a/exercises/enums/README.md b/exercises/enums/README.md new file mode 100644 index 00000000..f31a7139 --- /dev/null +++ b/exercises/enums/README.md @@ -0,0 +1,7 @@ +### Enums + +Rust allows you to define a type called `enums` which allow you to enumerate possible values. In combination with enums, we have the concept of `pattern matching` in Rust, which makes it easy to run different code for different values of an enumeration. Enums, while available in many languages, Rust's enums are most similar to `algebraic data types` in functional languages, such as F#, OCaml, and Haskell. + +#### Book Sections + +- [Enums](https://doc.rust-lang.org/book/ch06-00-enums.html) diff --git a/exercises/enums/enums1.rs b/exercises/enums/enums1.rs new file mode 100644 index 00000000..8b14f29c --- /dev/null +++ b/exercises/enums/enums1.rs @@ -0,0 +1,42 @@ +// enums1.rs +// Make me compile! Scroll down for hints! + +#[derive(Debug)] +enum Message { + // TODO: define a few types of messages as used below +} + +fn main() { + println!("{:?}", Message::Quit); + println!("{:?}", Message::Echo); + println!("{:?}", Message::Move); + println!("{:?}", Message::ChangeColor); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Hint: The declaration of the enumeration type has not been defined yet. diff --git a/exercises/enums/enums2.rs b/exercises/enums/enums2.rs new file mode 100644 index 00000000..71ac8397 --- /dev/null +++ b/exercises/enums/enums2.rs @@ -0,0 +1,61 @@ +// enums2.rs +// Make me compile! Scroll down for hints + +#[derive(Debug)] +enum Message { + // TODO: define the different variants used below +} + +impl Message { + fn call(&self) { + println!("{:?}", &self); + } +} + +fn main() { + let messages = [ + Message::Move{ x: 10, y: 30 }, + Message::Echo(String::from("hello world")), + Message::ChangeColor(200, 255, 255), + Message::Quit + ]; + + for message in &messages { + message.call(); + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// Hint: you can create enumerations that have different variants with different types +// such as no data, anonymous structs, a single string, tuples, ...etc diff --git a/exercises/enums/enums3.rs b/exercises/enums/enums3.rs new file mode 100644 index 00000000..c5d81bf9 --- /dev/null +++ b/exercises/enums/enums3.rs @@ -0,0 +1,63 @@ +// enums3.rs +// Address all the TODOs to make the tests pass! + +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 +} + +impl State { + fn change_color(&mut self, color: (u8, u8, u8)) { + self.color = color; + } + + fn quit(&mut self) { + self.quit = true; + } + + fn echo(&self, s: String) { + println!("{}", 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 + } +} + +#[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) + }; + state.process(Message::ChangeColor(255, 0, 255)); + state.process(Message::Echo(String::from("hello world"))); + state.process(Message::Move{ 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); + } + +} diff --git a/info.toml b/info.toml index 5e353344..454d358f 100644 --- a/info.toml +++ b/info.toml @@ -86,6 +86,20 @@ mode = "test" path = "exercises/structs/structs2.rs" mode = "test" +# ENUMS + +[[exercises]] +path = "exercises/enums/enums1.rs" +mode = "compile" + +[[exercises]] +path = "exercises/enums/enums2.rs" +mode = "compile" + +[[exercises]] +path = "exercises/enums/enums3.rs" +mode = "test" + # TESTS [[exercises]]