summaryrefslogtreecommitdiff
path: root/rustlings/exercises/13_error_handling
diff options
context:
space:
mode:
Diffstat (limited to 'rustlings/exercises/13_error_handling')
-rw-r--r--rustlings/exercises/13_error_handling/README.md12
-rw-r--r--rustlings/exercises/13_error_handling/errors1.rs40
-rw-r--r--rustlings/exercises/13_error_handling/errors2.rs50
-rw-r--r--rustlings/exercises/13_error_handling/errors3.rs33
-rw-r--r--rustlings/exercises/13_error_handling/errors4.rs44
-rw-r--r--rustlings/exercises/13_error_handling/errors5.rs56
-rw-r--r--rustlings/exercises/13_error_handling/errors6.rs91
7 files changed, 0 insertions, 326 deletions
diff --git a/rustlings/exercises/13_error_handling/README.md b/rustlings/exercises/13_error_handling/README.md
deleted file mode 100644
index 9b6674b..0000000
--- a/rustlings/exercises/13_error_handling/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# Error handling
-
-Most errors aren't serious enough to require the program to stop entirely.
-Sometimes, when a function fails, it's for a reason that you can easily interpret and respond to.
-For example, if you try to open a file and that operation fails because the file doesn't exist, you might want to create the file instead of terminating the process.
-
-## Further information
-
-- [Error Handling](https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html)
-- [Generics](https://doc.rust-lang.org/book/ch10-01-syntax.html)
-- [Result](https://doc.rust-lang.org/rust-by-example/error/result.html)
-- [Boxing errors](https://doc.rust-lang.org/rust-by-example/error/multiple_error_types/boxing_errors.html)
diff --git a/rustlings/exercises/13_error_handling/errors1.rs b/rustlings/exercises/13_error_handling/errors1.rs
deleted file mode 100644
index b9b9bd5..0000000
--- a/rustlings/exercises/13_error_handling/errors1.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// TODO: This function refuses to generate text to be printed on a nametag if
-// you pass it an empty string. It'd be nicer if it explained what the problem
-// was instead of just returning `None`. Thankfully, Rust has a similar
-// construct to `Option` that can be used to express error conditions. Change
-// the function signature and body to return `Result<String, String>` instead
-// of `Option<String>`.
-fn generate_nametag_text(name: String) -> Result<String, String> {
- if name.is_empty() {
- Err(String::from("Empty names aren't allowed"))
- } else {
- Ok(format!("Hi! My name is {name}"))
- }
-}
-
-fn main() {
- // You can optionally experiment here.
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn generates_nametag_text_for_a_nonempty_name() {
- assert_eq!(
- generate_nametag_text("Beyoncé".to_string()).as_deref(),
- Ok("Hi! My name is Beyoncé"),
- );
- }
-
- #[test]
- fn explains_why_generating_nametag_text_fails() {
- assert_eq!(
- generate_nametag_text(String::new())
- .as_ref()
- .map_err(|e| e.as_str()),
- Err("Empty names aren't allowed"),
- );
- }
-}
diff --git a/rustlings/exercises/13_error_handling/errors2.rs b/rustlings/exercises/13_error_handling/errors2.rs
deleted file mode 100644
index 3d850f7..0000000
--- a/rustlings/exercises/13_error_handling/errors2.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-// Say we're writing a game where you can buy items with tokens. All items cost
-// 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 cost of the items. Since
-// the player typed in the quantity, we get it as a string. They might have
-// typed anything, not just numbers!
-//
-// Right now, this function isn't handling the error case at all. What we want
-// to do is: If we call the `total_cost` function on a string that is not a
-// number, that function will return a `ParseIntError`. 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!
-
-use std::num::ParseIntError;
-
-fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
- let processing_fee = 1;
- let cost_per_item = 5;
-
- // TODO: Handle the error case as described above.
- let qty = item_quantity.parse::<i32>()?;
-
- Ok(qty * cost_per_item + processing_fee)
-}
-
-fn main() {
- // You can optionally experiment here.
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use std::num::IntErrorKind;
-
- #[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().kind(),
- &IntErrorKind::InvalidDigit,
- );
- }
-}
diff --git a/rustlings/exercises/13_error_handling/errors3.rs b/rustlings/exercises/13_error_handling/errors3.rs
deleted file mode 100644
index bf21bbc..0000000
--- a/rustlings/exercises/13_error_handling/errors3.rs
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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?
-
-use std::num::ParseIntError;
-
-// Don't change this function.
-fn total_cost(item_quantity: &str) -> Result<i32, ParseIntError> {
- let processing_fee = 1;
- let cost_per_item = 5;
- let qty = item_quantity.parse::<i32>()?;
-
- Ok(qty * cost_per_item + processing_fee)
-}
-
-// TODO: Fix the compiler error by changing the signature and body of the
-// `main` function.
-fn main() -> Result<(), ParseIntError> {
- let mut tokens = 100;
- let pretend_user_input = "8";
-
- // Don't change this line.
- let cost = total_cost(pretend_user_input)?;
-
- if cost > tokens {
- println!("You can't afford that many!");
- } else {
- tokens -= cost;
- println!("You now have {tokens} tokens.");
- }
-
- Ok(())
-}
diff --git a/rustlings/exercises/13_error_handling/errors4.rs b/rustlings/exercises/13_error_handling/errors4.rs
deleted file mode 100644
index e5f3d39..0000000
--- a/rustlings/exercises/13_error_handling/errors4.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-#[derive(PartialEq, Debug)]
-enum CreationError {
- Negative,
- Zero,
-}
-
-#[derive(PartialEq, Debug)]
-struct PositiveNonzeroInteger(u64);
-
-impl PositiveNonzeroInteger {
- fn new(value: i64) -> Result<Self, CreationError> {
- // TODO: This function shouldn't always return an `Ok`.
- // Read the tests below to clarify what should be returned.
- if value < 0 {
- return Err(CreationError::Negative);
- }
- if value == 0 {
- return Err(CreationError::Zero);
- }
- Ok(Self(value as u64))
- }
-}
-
-fn main() {
- // You can optionally experiment here.
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn test_creation() {
- assert_eq!(
- PositiveNonzeroInteger::new(10),
- Ok(PositiveNonzeroInteger(10)),
- );
- assert_eq!(
- PositiveNonzeroInteger::new(-10),
- Err(CreationError::Negative),
- );
- assert_eq!(PositiveNonzeroInteger::new(0), Err(CreationError::Zero));
- }
-}
diff --git a/rustlings/exercises/13_error_handling/errors5.rs b/rustlings/exercises/13_error_handling/errors5.rs
deleted file mode 100644
index 405f0dc..0000000
--- a/rustlings/exercises/13_error_handling/errors5.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// This exercise is an altered version of the `errors4` exercise. It uses some
-// concepts that we won't get to until later in the course, like `Box` and the
-// `From` trait. It's not important to understand them in detail right now, but
-// you can read ahead if you like. For now, think of the `Box<dyn ???>` type as
-// an "I want anything that does ???" type.
-//
-// In short, this particular use case for boxes is for when you want to own a
-// value and you care only that it is a type which implements a particular
-// trait. To do so, the `Box` is declared as of type `Box<dyn Trait>` where
-// `Trait` is the trait the compiler looks for on any value used in that
-// context. For this exercise, that context is the potential errors which
-// can be returned in a `Result`.
-
-use std::error::Error;
-use std::fmt;
-
-#[derive(PartialEq, Debug)]
-enum CreationError {
- Negative,
- Zero,
-}
-
-// This is required so that `CreationError` can implement `Error`.
-impl fmt::Display for CreationError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- let description = match *self {
- CreationError::Negative => "number is negative",
- CreationError::Zero => "number is zero",
- };
- f.write_str(description)
- }
-}
-
-impl Error for CreationError {}
-
-#[derive(PartialEq, Debug)]
-struct PositiveNonzeroInteger(u64);
-
-impl PositiveNonzeroInteger {
- fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
- match value {
- x if x < 0 => Err(CreationError::Negative),
- 0 => Err(CreationError::Zero),
- x => Ok(PositiveNonzeroInteger(x as u64)),
- }
- }
-}
-
-// TODO: Add the correct return type `Result<(), Box<dyn ???>>`. What can we
-// use to describe both errors? Is there a trait which both errors implement?
-fn main() -> Result<(), Box<dyn Error>> {
- let pretend_user_input = "42";
- let x: i64 = pretend_user_input.parse()?;
- println!("output={:?}", PositiveNonzeroInteger::new(x)?);
- Ok(())
-}
diff --git a/rustlings/exercises/13_error_handling/errors6.rs b/rustlings/exercises/13_error_handling/errors6.rs
deleted file mode 100644
index 353b50b..0000000
--- a/rustlings/exercises/13_error_handling/errors6.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-// Using catch-all error types like `Box<dyn Error>` isn't recommended for
-// library code where callers might want to make decisions based on the error
-// content instead of printing it out or propagating it further. Here, we define
-// a custom error type to make it possible for callers to decide what to do next
-// when our function returns an error.
-
-use std::num::ParseIntError;
-
-#[derive(PartialEq, Debug)]
-enum CreationError {
- Negative,
- Zero,
-}
-
-// A custom error type that we will be using in `PositiveNonzeroInteger::parse`.
-#[derive(PartialEq, Debug)]
-enum ParsePosNonzeroError {
- Creation(CreationError),
- ParseInt(ParseIntError),
-}
-
-impl ParsePosNonzeroError {
- fn from_creation(err: CreationError) -> Self {
- Self::Creation(err)
- }
-
- // TODO: Add another error conversion function here.
- fn from_parse_int(err: ParseIntError) -> Self {
- Self::ParseInt(err)
- }
-}
-
-#[derive(PartialEq, Debug)]
-struct PositiveNonzeroInteger(u64);
-
-impl PositiveNonzeroInteger {
- fn new(value: i64) -> Result<Self, CreationError> {
- match value {
- x if x < 0 => Err(CreationError::Negative),
- 0 => Err(CreationError::Zero),
- x => Ok(Self(x as u64)),
- }
- }
-
- fn parse(s: &str) -> Result<Self, ParsePosNonzeroError> {
- // TODO: change this to return an appropriate error instead of panicking
- // when `parse()` returns an error.
- let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parse_int)?;
- Self::new(x).map_err(ParsePosNonzeroError::from_creation)
- }
-}
-
-fn main() {
- // You can optionally experiment here.
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn test_parse_error() {
- assert!(matches!(
- PositiveNonzeroInteger::parse("not a number"),
- Err(ParsePosNonzeroError::ParseInt(_)),
- ));
- }
-
- #[test]
- fn test_negative() {
- assert_eq!(
- PositiveNonzeroInteger::parse("-555"),
- Err(ParsePosNonzeroError::Creation(CreationError::Negative)),
- );
- }
-
- #[test]
- fn test_zero() {
- assert_eq!(
- PositiveNonzeroInteger::parse("0"),
- Err(ParsePosNonzeroError::Creation(CreationError::Zero)),
- );
- }
-
- #[test]
- fn test_positive() {
- let x = PositiveNonzeroInteger::new(42).unwrap();
- assert_eq!(x.0, 42);
- assert_eq!(PositiveNonzeroInteger::parse("42"), Ok(x));
- }
-}