Lab 4: Errors
The code we wrote live:
use std::fs::read_to_string; use std::io; use std::process::exit; use std::num::ParseIntError; use thiserror::Error; #[derive(Debug, Error)] pub enum MainError { #[error("an io error occured: {0}")] IoError(#[from] io::Error), #[error("an divide error occured: {0}")] DivideError(#[from] DivideError), #[error("couldn't parse int: {0}")] ParseIntError(#[from] ParseIntError), #[error("not enough parts on line")] NotEnoughParts } #[derive(Debug, Error)] pub enum DivideError { #[error("divide 1 failed")] FirstFailed, #[error("divide 2 failed")] SecondFailed, } pub fn divide_three(a: u64, b: u64, c: u64) -> Result<u64, DivideError> { let r1 = divide(a, b).ok_or(DivideError::FirstFailed)?; let r2 = divide(r1, c).ok_or(DivideError::SecondFailed)?; Ok(r2) } pub fn divide(a: u64, b: u64) -> Option<u64> { if b == 0 { None } else { Some(a / b) } } fn process_integers(inputs: &[(u64, u64, u64)]) -> Result<Vec<u64>, DivideError> { let mut res = Vec::new(); for &(a, b, c) in inputs { let answer = divide_three(a, b, c); match answer { Ok(i) => res.push(i), Err(e) => { return Err(e); } } } Ok(res) } fn read_and_process() -> Result<(), MainError> { // numbers.csv contains: // 20, 2, 3 // 12, 0, 5 // 58, 3, 0 let contents = read_to_string("src/numbers.csv")?; let mut numbers = Vec::new(); for i in contents.lines() { let mut splitter = i.split(','); let first = splitter.next().ok_or(MainError::NotEnoughParts)?; let second = splitter.next().ok_or(MainError::NotEnoughParts)?; let third = splitter.next().ok_or(MainError::NotEnoughParts)?; let first_int = first.trim().parse()?; let second_int = second.trim().parse()?; let third_int = third.trim().parse()?; numbers.push((first_int, second_int, third_int)); } let res = process_integers(&numbers)?; println!("{res:?}"); Ok(()) } #[test] fn test_right_error() { assert_eq!(Err(DivideError::FirstFailed), process_integers(&[(1, 0, 4)])) } fn main() { if let Err(e) = read_and_process() { eprintln!("{}", e); exit(1); } }