summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exercises/13_error_handling/errors5.rs76
-rw-r--r--rustlings-macros/info.toml17
-rw-r--r--solutions/13_error_handling/errors5.rs55
3 files changed, 96 insertions, 52 deletions
diff --git a/exercises/13_error_handling/errors5.rs b/exercises/13_error_handling/errors5.rs
index 7192562..d0044db 100644
--- a/exercises/13_error_handling/errors5.rs
+++ b/exercises/13_error_handling/errors5.rs
@@ -1,38 +1,18 @@
-// This program uses an altered version of the code from errors4.
-//
-// This exercise 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, which,
-// given Rust's usual standards for runtime safety, should strike you as
-// somewhat lenient!
+// 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.
-//
-// What can we use to describe both errors? In other words, is there a trait
-// which both errors implement?
+// 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;
+use std::error::Error;
use std::fmt;
-use std::num::ParseIntError;
-
-// TODO: update the return type of `main()` to make this compile.
-fn main() -> Result<(), Box<dyn ???>> {
- let pretend_user_input = "42";
- let x: i64 = pretend_user_input.parse()?;
- println!("output={:?}", PositiveNonzeroInteger::new(x)?);
- Ok(())
-}
-
-// Don't change anything below this line.
-
-#[derive(PartialEq, Debug)]
-struct PositiveNonzeroInteger(u64);
#[derive(PartialEq, Debug)]
enum CreationError {
@@ -40,17 +20,7 @@ enum CreationError {
Zero,
}
-impl PositiveNonzeroInteger {
- fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
- match value {
- x if x < 0 => Err(CreationError::Negative),
- x if x == 0 => Err(CreationError::Zero),
- x => Ok(PositiveNonzeroInteger(x as u64)),
- }
- }
-}
-
-// This is required so that `CreationError` can implement `error::Error`.
+// 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 {
@@ -61,4 +31,26 @@ impl fmt::Display for CreationError {
}
}
-impl error::Error for CreationError {}
+impl Error for CreationError {}
+
+#[derive(PartialEq, Debug)]
+struct PositiveNonzeroInteger(u64);
+
+impl PositiveNonzeroInteger {
+ fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
+ match value {
+ 0 => Err(CreationError::Zero),
+ x if x < 0 => Err(CreationError::Negative),
+ 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() {
+ let pretend_user_input = "42";
+ let x: i64 = pretend_user_input.parse()?;
+ println!("output={:?}", PositiveNonzeroInteger::new(x)?);
+ Ok(())
+}
diff --git a/rustlings-macros/info.toml b/rustlings-macros/info.toml
index d39044c..700c179 100644
--- a/rustlings-macros/info.toml
+++ b/rustlings-macros/info.toml
@@ -692,24 +692,23 @@ name = "errors5"
dir = "13_error_handling"
test = false
hint = """
-There are two different possible `Result` types produced within `main()`, which
-are propagated using `?` operators. How do we declare a return type from
-`main()` that allows both?
+There are two different possible `Result` types produced within the `main`
+function, which are propagated using the `?` operators. How do we declare a
+return type for the `main` function that allows both?
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>`. This boxed trait
-object is polymorphic, and since all errors implement the `error::Error` trait,
-we can capture lots of different errors in one "Box" object.
+convert it to a boxed trait object, a `Box<dyn Error>`. This boxed trait object
+is polymorphic, and since all errors implement the `Error` trait, we can capture
+lots of different errors in one `Box` object.
-Check out this section of the book:
+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
Read more about boxing errors:
https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/boxing_errors.html
Read more about using the `?` operator with boxed errors:
-https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html
-"""
+https://doc.rust-lang.org/stable/rust-by-example/error/multiple_error_types/reenter_question_mark.html"""
[[exercises]]
name = "errors6"
diff --git a/solutions/13_error_handling/errors5.rs b/solutions/13_error_handling/errors5.rs
index 4e18198..c1424ee 100644
--- a/solutions/13_error_handling/errors5.rs
+++ b/solutions/13_error_handling/errors5.rs
@@ -1 +1,54 @@
-// Solutions will be available before the stable release. Thank you for testing the beta version 🥰
+// 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)),
+ }
+ }
+}
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let pretend_user_input = "42";
+ let x: i64 = pretend_user_input.parse()?;
+ println!("output={:?}", PositiveNonzeroInteger::new(x)?);
+ Ok(())
+}