diff --git a/d07/src/utils.rs b/d07/src/utils.rs index 7b799fc..54712de 100644 --- a/d07/src/utils.rs +++ b/d07/src/utils.rs @@ -1,25 +1,59 @@ use std::fmt; use std::str::FromStr; +#[derive(Debug)] +struct NestedParseError { + message: String, + wraps: Option>, +} + +impl fmt::Display for NestedParseError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.message) + } +} + +impl NestedParseError { + fn new(message: &str) -> Self { + NestedParseError { + message: String::from(message), + wraps: None, + } + } + + fn new_wraps(message: &str, wraps: Box) -> Self { + NestedParseError { + message: String::from(message), + wraps: Some(wraps), + } + } +} + /// Returns a vector of items parsed from a delimited string /// /// # Arguments /// /// * `input` input string to split and parse from /// * `delimiter` item delimiter -pub fn parse_delimited(input: &str, delimiter: &str) -> Vec +pub fn parse_delimited(input: &str, delimiter: &str) -> Result, NestedParseError> where T: FromStr, - ::Err: fmt::Debug, + ::Err: std::error::Error, { - input + let results: Vec::Err>> = input .split(delimiter) - .map(|v| { - v.trim() - .parse::() - .expect(format!("Unable to parse '{}' from text '{}'", v, input).as_str()) - }) - .collect() + .map(|v| v.trim().parse::()) + .collect(); + + let first_error = results.iter().find_map(|r| r.err()); + if let Some(err) = first_error { + return Err(NestedParseError::new_wraps( + format!("Error parsing input {}", input).as_str(), + err, + )); + } else { + return Ok(results.iter().map(|v| v.unwrap()).collect::>()); + } } /// Returns a string with each element of the vector formatted and joined