diff options
| author | apogeeoak <59737221+apogeeoak@users.noreply.github.com> | 2022-02-04 19:27:42 -0500 |
|---|---|---|
| committer | apogeeoak <59737221+apogeeoak@users.noreply.github.com> | 2022-02-04 19:27:42 -0500 |
| commit | c1f35e46dffc63e1c8660b8e1fc91e9a9fca3e39 (patch) | |
| tree | 6d25f2fcd6e0de9d09f588ae33f7017c34cd31c9 /exercises/advanced_errors/advanced_errs1.rs | |
| parent | f78c48020830d7900dd8d81f355606581670446d (diff) | |
| parent | cd2b5e8e3b616e769d2c17df45f813772aa81530 (diff) | |
Merge branch 'main' into text
Diffstat (limited to 'exercises/advanced_errors/advanced_errs1.rs')
| -rw-r--r-- | exercises/advanced_errors/advanced_errs1.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/exercises/advanced_errors/advanced_errs1.rs b/exercises/advanced_errors/advanced_errs1.rs new file mode 100644 index 0000000..4bc7b63 --- /dev/null +++ b/exercises/advanced_errors/advanced_errs1.rs @@ -0,0 +1,98 @@ +// advanced_errs1.rs + +// Remember back in errors6, we had multiple mapping functions so that we +// could translate lower-level errors into our custom error type using +// `map_err()`? What if we could use the `?` operator directly instead? + +// Make this code compile! Execute `rustlings hint advanced_errs1` for +// hints :) + +// I AM NOT DONE + +use std::num::ParseIntError; +use std::str::FromStr; + +// This is a custom error type that we will be using in the `FromStr` +// implementation. +#[derive(PartialEq, Debug)] +enum ParsePosNonzeroError { + Creation(CreationError), + ParseInt(ParseIntError), +} + +impl From<CreationError> for ParsePosNonzeroError { + fn from(e: CreationError) -> Self { + // TODO: complete this implementation so that the `?` operator will + // work for `CreationError` + } +} + +// TODO: implement another instance of the `From` trait here so that the +// `?` operator will work in the other place in the `FromStr` +// implementation below. + +// Don't change anything below this line. + +impl FromStr for PositiveNonzeroInteger { + type Err = ParsePosNonzeroError; + fn from_str(s: &str) -> Result<PositiveNonzeroInteger, Self::Err> { + let x: i64 = s.parse()?; + Ok(PositiveNonzeroInteger::new(x)?) + } +} + +#[derive(PartialEq, Debug)] +struct PositiveNonzeroInteger(u64); + +#[derive(PartialEq, Debug)] +enum CreationError { + Negative, + 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)), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_parse_error() { + // We can't construct a ParseIntError, so we have to pattern match. + assert!(matches!( + PositiveNonzeroInteger::from_str("not a number"), + Err(ParsePosNonzeroError::ParseInt(_)) + )); + } + + #[test] + fn test_negative() { + assert_eq!( + PositiveNonzeroInteger::from_str("-555"), + Err(ParsePosNonzeroError::Creation(CreationError::Negative)) + ); + } + + #[test] + fn test_zero() { + assert_eq!( + PositiveNonzeroInteger::from_str("0"), + Err(ParsePosNonzeroError::Creation(CreationError::Zero)) + ); + } + + #[test] + fn test_positive() { + let x = PositiveNonzeroInteger::new(42); + assert!(x.is_ok()); + assert_eq!(PositiveNonzeroInteger::from_str("42"), Ok(x.unwrap())); + } +} |
