Skip to content

Instantly share code, notes, and snippets.

@totechite
Created October 6, 2018 18:11
Show Gist options
  • Save totechite/5f23267178c4defda21f0eebcf26d49e to your computer and use it in GitHub Desktop.
Save totechite/5f23267178c4defda21f0eebcf26d49e to your computer and use it in GitHub Desktop.
Practice Error Handling on rustlings.
// 5 tokens, and whenever you purchase items there is a processing fee of 1
// token. A player of the game will type in how many items they want to buy,
// and the `total_cost` function will calculate the total number of tokens.
// Since the player typed in the quantity, though, we get it as a string-- and
// they might have typed anything, not just numbers!
// Right now, this function isn't handling the error case at all (and isn't
// handling the success case properly either). What we want to do is:
// if we call the `parse` function on a string that is not a number, that
// function will return a `ParseIntError`, and in that case, we want to
// immediately return that error from our function and not try to multiply
// 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.
use std::num::ParseIntError;
pub fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
let processing_fee = 1;
let cost_per_item = 5;
let qty = item_quantity.parse::<i32>();
match qty {
Ok(x) => Ok(x * cost_per_item + processing_fee),
Err(x) => Err(x)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn item_quantity_is_a_valid_number() {
assert_eq!(
total_cost("34"),
Ok(171)
);
}
#[test]
fn item_quantity_is_an_invalid_number() {
assert_eq!(
total_cost("beep boop").unwrap_err().to_string(),
"invalid digit found in string"
);
}
}
// 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/stable/book/second-edition/ch09-02-recoverable-errors-with-result.html#a-shortcut-for-propagating-errors-the--operator
// and give it a try!
// option1.rs
// 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 :)
fn main() {
let mut list = vec![3];
let last = list.pop().unwrap();
println!("The last item in the list is {:?}", last);
let second_to_last = list.pop().unwrap_or(3);
println!("The second-to-last item in the list is {:?}", second_to_last);
}
// 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!
// result1.rs
// Make this test pass! Scroll down for hints :)
#[derive(PartialEq,Debug)]
struct PositiveNonzeroInteger(u64);
#[derive(PartialEq,Debug)]
enum CreationError {
Negative,
Zero,
}
impl PositiveNonzeroInteger {
fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
if value == 0 {
Err(CreationError::Zero)
}else if value < 0{
Err(CreationError::Negative)
}else{
Ok(PositiveNonzeroInteger(value as u64))
}
}
}
#[test]
fn test_creation() {
assert!(PositiveNonzeroInteger::new(10).is_ok());
assert_eq!(Err(CreationError::Negative), PositiveNonzeroInteger::new(-10));
assert_eq!(Err(CreationError::Zero), PositiveNonzeroInteger::new(0));
}
// `PositiveNonzeroInteger::new` is always creating a new instance and returning an `Ok` result.
// It should be doing some checking, returning an `Err` result if those checks fail, and only
// returning an `Ok` result if those checks determine that everything is... okay :)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment