//! Your task is to implement the missing conversions to `Error`. //! //! If the solution seems repetitive, the `thiserror` exercise will scratch that //! itch. use std::num::ParseIntError; use std::str::FromStr; #[derive(PartialEq, Debug)] enum Error { /// A [`CreationError`] from creating the [`PositiveInteger`]. Creation(CreationError), /// A [`ParseIntError`] from parsing the input string. ParseInt(ParseIntError), } // TODO impl From... // Don't change anything below this line. // Note: using `FromStr` rather than `From<&str>` is better if the parsing can // fail. `from_str` is rarely used directly, but it's counterpart `str::parse` // uses it in the background. Read more about `FromStr`: // https://doc.rust-lang.org/std/str/trait.FromStr.html impl FromStr for PositiveNonzeroInteger { type Err = Error; fn from_str(s: &str) -> Result { 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 { match value { 0 => Err(CreationError::Zero), 1.. => Ok(PositiveNonzeroInteger(value as u64)), _ => Err(CreationError::Negative), } } } #[cfg(test)] mod test { use super::*; #[test] fn test_parse_error() { assert!(matches!( PositiveNonzeroInteger::from_str("not a number"), Err(Error::ParseInt(_)) )); } #[test] fn test_negative() { assert_eq!( PositiveNonzeroInteger::from_str("-555"), Err(Error::Creation(CreationError::Negative)) ); } #[test] fn test_zero() { assert_eq!( PositiveNonzeroInteger::from_str("0"), Err(Error::Creation(CreationError::Zero)) ); } #[test] fn test_positive() { let x = PositiveNonzeroInteger::new(42); assert!(x.is_ok()); assert_eq!(PositiveNonzeroInteger::from_str("42").unwrap(), x.unwrap()); } }