From 7479a4737bdcac347322ad0883ca528c8675e720 Mon Sep 17 00:00:00 2001 From: AlexandruGG Date: Tue, 26 May 2020 21:46:24 +0100 Subject: [PATCH 1/3] feat: Add box1.rs exercise --- exercises/standard_library_types/README.md | 2 ++ exercises/standard_library_types/box1.rs | 35 ++++++++++++++++++++++ info.toml | 18 +++++++++++ 3 files changed, 55 insertions(+) create mode 100644 exercises/standard_library_types/box1.rs diff --git a/exercises/standard_library_types/README.md b/exercises/standard_library_types/README.md index d138d874d8..36b30c1fd4 100644 --- a/exercises/standard_library_types/README.md +++ b/exercises/standard_library_types/README.md @@ -1,3 +1,5 @@ +For the Box exercise check out the chapter [Using Box to Point to Data on the Heap](https://doc.rust-lang.org/book/ch15-01-box.html). + For the Arc exercise check out the chapter [Shared-State Concurrency](https://doc.rust-lang.org/book/ch16-03-shared-state.html) of the Rust Book. For the Iterator exercise check out the chapters [Iterator](https://doc.rust-lang.org/book/ch13-02-iterators.html) of the Rust Book and the [Iterator documentation](https://doc.rust-lang.org/stable/std/iter/). diff --git a/exercises/standard_library_types/box1.rs b/exercises/standard_library_types/box1.rs new file mode 100644 index 0000000000..11156ea092 --- /dev/null +++ b/exercises/standard_library_types/box1.rs @@ -0,0 +1,35 @@ +// box1.rs +// +// At compile time, Rust needs to know how much space a type takes up. This becomes problematic +// for recursive types, where a value can have as part of itself another value of the same type. +// To get around the issue, we can use a `Box` - a smart pointer used to store data on the heap, +// which also allows us to wrap a recursive type. +// +// The recursive type we're implementing in this exercise is the `cons list` - a data structure +// frequently found in functional programming languages. Each item in a cons list contains two +// elements: the value of the current item and the next item. The last item is a value called `Nil`. +// +// Step 1: use a `Box` in the enum definition to make the code compile +// Step 2: create both empty and non-empty cons lists of by replacing `unimplemented!()` +// +// Execute `rustlings hint box1` for hints :) + +// I AM NOT DONE + +#[derive(PartialEq, Debug)] +enum List { + Cons(i32, List), + Nil, +} + +fn main() { + let empty_list = unimplemented!(); + println!("This is an empty cons list: {:?}", empty_list); + + let non_empty_list = unimplemented!(); + println!("This is a non-empty cons list: {:?}", non_empty_list); + + // Do not change these + assert_eq!(List::Nil, empty_list); + assert_ne!(empty_list, non_empty_list); +} diff --git a/info.toml b/info.toml index e2aa82a7f8..dcd93bf227 100644 --- a/info.toml +++ b/info.toml @@ -614,6 +614,24 @@ hint = """ # STANDARD LIBRARY TYPES +[[exercises]] +name = "box1" +path = "exercises/standard_library_types/box1.rs" +mode = "compile" +hint = """ +Step 1 +The compiler's message should help: since we cannot store the value of the actual type +when working with recursive types, we need to store a reference (pointer) to its value. +We should therefore place our `List` inside a `Box`. More details in the book here: +https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes + +Step 2 +Creating an empty list should be fairly straightforward (hint: peek at the assertions). +For a non-empty list keep in mind that wee want to use our Cons "list builder". +Although the current list is one of integers (i32), feel free to change the definition +and try other types! +""" + [[exercises]] name = "arc1" path = "exercises/standard_library_types/arc1.rs" From df81141d6fb3f43a7a035c4efc1150b6ede0b472 Mon Sep 17 00:00:00 2001 From: AlexandruGG Date: Wed, 27 May 2020 10:03:59 +0100 Subject: [PATCH 2/3] Address PR feedback: add tests --- exercises/standard_library_types/box1.rs | 34 ++++++++++++++++++------ info.toml | 6 ++--- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/exercises/standard_library_types/box1.rs b/exercises/standard_library_types/box1.rs index 11156ea092..2248962ef1 100644 --- a/exercises/standard_library_types/box1.rs +++ b/exercises/standard_library_types/box1.rs @@ -12,24 +12,42 @@ // Step 1: use a `Box` in the enum definition to make the code compile // Step 2: create both empty and non-empty cons lists of by replacing `unimplemented!()` // +// Note: the tests should not be changed +// // Execute `rustlings hint box1` for hints :) // I AM NOT DONE #[derive(PartialEq, Debug)] -enum List { +pub enum List { Cons(i32, List), Nil, } fn main() { - let empty_list = unimplemented!(); - println!("This is an empty cons list: {:?}", empty_list); + println!("This is an empty cons list: {:?}", create_empty_list()); + println!("This is a non-empty cons list: {:?}", create_non_empty_list()); +} + +pub fn create_empty_list() -> List { + unimplemented!() +} + +pub fn create_non_empty_list() -> List { + unimplemented!() +} + +#[cfg(test)] +mod tests { + use super::*; - let non_empty_list = unimplemented!(); - println!("This is a non-empty cons list: {:?}", non_empty_list); + #[test] + fn test_create_empty_list() { + assert_eq!(List::Nil, create_empty_list()) + } - // Do not change these - assert_eq!(List::Nil, empty_list); - assert_ne!(empty_list, non_empty_list); + #[test] + fn test_create_non_empty_list() { + assert_ne!(create_empty_list(), create_non_empty_list()) + } } diff --git a/info.toml b/info.toml index dcd93bf227..842253c55e 100644 --- a/info.toml +++ b/info.toml @@ -617,17 +617,17 @@ hint = """ [[exercises]] name = "box1" path = "exercises/standard_library_types/box1.rs" -mode = "compile" +mode = "test" hint = """ Step 1 The compiler's message should help: since we cannot store the value of the actual type when working with recursive types, we need to store a reference (pointer) to its value. -We should therefore place our `List` inside a `Box`. More details in the book here: +We should, therefore, place our `List` inside a `Box`. More details in the book here: https://doc.rust-lang.org/book/ch15-01-box.html#enabling-recursive-types-with-boxes Step 2 Creating an empty list should be fairly straightforward (hint: peek at the assertions). -For a non-empty list keep in mind that wee want to use our Cons "list builder". +For a non-empty list keep in mind that we want to use our Cons "list builder". Although the current list is one of integers (i32), feel free to change the definition and try other types! """ From 7e79c512225eb2a302db7f9b041c736b806e97f4 Mon Sep 17 00:00:00 2001 From: AlexandruGG Date: Thu, 28 May 2020 18:01:32 +0100 Subject: [PATCH 3/3] Add .idea to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index de87c1e74c..6094e5c1e9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ target/ *.pdb exercises/clippy/Cargo.toml exercises/clippy/Cargo.lock +.idea