1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
use std::num::ParseIntError;
#[derive(PartialEq, Debug)] enum ParsePosNonzeroError { Creation(CreationError), ParseInt(ParseIntError), }
impl ParsePosNonzeroError { fn from_creation(err: CreationError) -> ParsePosNonzeroError { ParsePosNonzeroError::Creation(err) } fn from_parseint(err:ParseIntError)-> ParsePosNonzeroError { ParsePosNonzeroError::ParseInt(err) } }
fn parse_pos_nonzero(s: &str) -> Result<PositiveNonzeroInteger, ParsePosNonzeroError> { let x: i64 = s.parse().map_err(ParsePosNonzeroError::from_parseint)?;
PositiveNonzeroInteger::new(x).map_err(ParsePosNonzeroError::from_creation)
}
#[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() { assert!(matches!( parse_pos_nonzero("not a number"), Err(ParsePosNonzeroError::ParseInt(_)) )); }
#[test] fn test_negative() { assert_eq!( parse_pos_nonzero("-555"), Err(ParsePosNonzeroError::Creation(CreationError::Negative)) ); }
#[test] fn test_zero() { assert_eq!( parse_pos_nonzero("0"), Err(ParsePosNonzeroError::Creation(CreationError::Zero)) ); }
#[test] fn test_positive() { let x = PositiveNonzeroInteger::new(42); assert!(x.is_ok()); assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap())); } }
|