mirror of https://github.com/sunface/rust-course
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					99 lines
				
				2.6 KiB
			
		
		
			
		
	
	
					99 lines
				
				2.6 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								// 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()));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |