diff options
| author | mo8it <mo8it@proton.me> | 2024-06-27 01:12:50 +0200 |
|---|---|---|
| committer | mo8it <mo8it@proton.me> | 2024-06-27 01:12:50 +0200 |
| commit | b1daea1fe8536d7b7b4463cb8fc36d69848ef77a (patch) | |
| tree | 45cd0559e57354a06ad76cef54024faa7a735d25 /solutions | |
| parent | 129884aff74964d13aba8309014554b5625d6e5b (diff) | |
errors6 solution
Diffstat (limited to 'solutions')
| -rw-r--r-- | solutions/13_error_handling/errors6.rs | 93 |
1 files changed, 92 insertions, 1 deletions
diff --git a/solutions/13_error_handling/errors6.rs b/solutions/13_error_handling/errors6.rs index 4e18198..70680cf 100644 --- a/solutions/13_error_handling/errors6.rs +++ b/solutions/13_error_handling/errors6.rs @@ -1 +1,92 @@ -// Solutions will be available before the stable release. Thank you for testing the beta version 🥰 +// 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) + } + + fn from_parseint(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), + x if x == 0 => Err(CreationError::Zero), + x => Ok(Self(x as u64)), + } + } + + fn parse(s: &str) -> Result<Self, ParsePosNonzeroError> { + // Return an appropriate error instead of panicking when `parse()` + // returns an error. + let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parseint)?; + // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Self::new(x).map_err(ParsePosNonzeroError::from_creation) + } +} + +fn main() { + // You can optionally experiment here. +} + +#[cfg(test)] +mod test { + use super::*; + use std::num::IntErrorKind; + + #[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)); + } +} |
