Skip to content

Commit

Permalink
feat: Refactor hint system
Browse files Browse the repository at this point in the history
Hints are now accessible using the CLI subcommand `rustlings hint
<exercise name`.

BREAKING CHANGE: This fundamentally changes the way people interact with exercises.
  • Loading branch information
marisa committed Nov 11, 2019
1 parent 627cdc0 commit 9bdb0a1
Show file tree
Hide file tree
Showing 47 changed files with 400 additions and 1,681 deletions.
30 changes: 1 addition & 29 deletions exercises/enums/enums1.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// enums1.rs
// Make me compile! Scroll down for hints!
// Make me compile! Execute `rustlings hint enums1` for hints!

#[derive(Debug)]
enum Message {
Expand All @@ -12,31 +12,3 @@ fn main() {
println!("{:?}", Message::Move);
println!("{:?}", Message::ChangeColor);
}



























// Hint: The declaration of the enumeration type has not been defined yet.
37 changes: 1 addition & 36 deletions exercises/enums/enums2.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// enums2.rs
// Make me compile! Scroll down for hints
// Make me compile! Execute `rustlings hint enums2` for hints!

#[derive(Debug)]
enum Message {
Expand All @@ -24,38 +24,3 @@ fn main() {
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
35 changes: 1 addition & 34 deletions exercises/error_handling/errors1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// was, instead of just sometimes returning `None`. The 2nd test currently
// does not compile or pass, but it illustrates the behavior we would like
// this function to have.
// Scroll down for hints!!!
// Execute `rustlings hint errors1` for hints!

pub fn generate_nametag_text(name: String) -> Option<String> {
if name.len() > 0 {
Expand Down Expand Up @@ -38,36 +38,3 @@ mod tests {
);
}
}




















// `Err` is one of the variants of `Result`, so what the 2nd test is saying
// is that `generate_nametag_text` should return a `Result` instead of an
// `Option`.

// To make this change, you'll need to:
// - update the return type in the function signature to be a Result<String, String> that
// could be the variants `Ok(String)` and `Err(String)`
// - change the body of the function to return `Ok(stuff)` where it currently
// returns `Some(stuff)`
// - change the body of the function to return `Err(error message)` where it
// currently returns `None`
// - change the first test to expect `Ok(stuff)` where it currently expects
// `Some(stuff)`.
26 changes: 1 addition & 25 deletions exercises/error_handling/errors2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// and add.

// There are at least two ways to implement this that are both correct-- but
// one is a lot shorter! Scroll down for hints to both ways.
// one is a lot shorter! Execute `rustlings hint errors2` for hints to both ways.

use std::num::ParseIntError;

Expand Down Expand Up @@ -43,27 +43,3 @@ mod tests {
);
}
}

















// One way to handle this is using a `match` statement on
// `item_quantity.parse::<i32>()` where the cases are `Ok(something)` and
// `Err(something)`. This pattern is very common in Rust, though, so there's
// a `?` operator that does pretty much what you would make that match statement
// do for you! Take a look at this section of the Error Handling chapter:
// https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
// and give it a try!
22 changes: 2 additions & 20 deletions exercises/error_handling/errors3.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// errors3.rs
// This is a program that is trying to use a completed version of the
// `total_cost` function from the previous exercise. It's not working though!
// Why not? What should we do to fix it? Scroll for hints!
// Why not? What should we do to fix it?
// Execute `rustlings hint errors3` for hints!

use std::num::ParseIntError;

Expand All @@ -26,22 +27,3 @@ pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {

Ok(qty * cost_per_item + processing_fee)
}


















// If other functions can return a `Result`, why shouldn't `main`?
137 changes: 1 addition & 136 deletions exercises/error_handling/errorsn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// type goes where the question marks are, and how do we return
// that type from the body of read_and_validate?
//
// Scroll down for hints :)
// Execute `rustlings hint errors4` for hints :)

use std::error;
use std::fmt;
Expand Down Expand Up @@ -110,138 +110,3 @@ impl error::Error for CreationError {
}
}
}































// First hint: To figure out what type should go where the ??? is, take a look
// at the test helper function `test_with_str`, since it returns whatever
// `read_and_validate` returns and`test_with_str` has its signature fully
// specified.




















// Next hint: There are three places in `read_and_validate` that we call a
// function that returns a `Result` (that is, the functions might fail).
// Apply the `?` operator on those calls so that we return immediately from
// `read_and_validate` if those function calls fail.




















// Another hint: under the hood, the `?` operator calls `From::from`
// on the error value to convert it to a boxed trait object, a Box<dyn error::Error>,
// which is polymorphic-- that means that lots of different kinds of errors
// can be returned from the same function because all errors act the same
// since they all implement the `error::Error` trait.
// Check out this section of the book:
// https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator




















// Another another hint: Note that because the `?` operator returns
// the *unwrapped* value in the `Ok` case, if we want to return a `Result` from
// `read_and_validate` for *its* success case, we'll have to rewrap a value
// that we got from the return value of a `?`ed call in an `Ok`-- this will
// look like `Ok(something)`.




















// Another another another hint: `Result`s must be "used", that is, you'll
// get a warning if you don't handle a `Result` that you get in your
// function. Read more about that in the `std::result` module docs:
// https://doc.rust-lang.org/std/result/#results-must-be-used
30 changes: 1 addition & 29 deletions exercises/error_handling/option1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// This example panics because the second time it calls `pop`, the `vec`
// is empty, so `pop` returns `None`, and `unwrap` panics if it's called
// on `None`. Handle this in a more graceful way than calling `unwrap`!
// Scroll down for hints :)
// Execute `rustlings hint option1` for hints :)

pub fn pop_too_much() -> bool {
let mut list = vec![3];
Expand All @@ -27,31 +27,3 @@ mod tests {
assert!(pop_too_much());
}
}























// Try using a `match` statement where the arms are `Some(thing)` and `None`.
// Or set a default value to print out if you get `None` by using the
// function `unwrap_or`.
// Or use an `if let` statement on the result of `pop()` to both destructure
// a `Some` value and only print out something if we have a value!
Loading

0 comments on commit 9bdb0a1

Please sign in to comment.