Try to build better error handling and wrapping with std

This commit is contained in:
IamTheFij 2021-12-09 14:00:57 -08:00
parent 668f206a86
commit bfa6da7b90

View File

@ -1,25 +1,59 @@
use std::fmt;
use std::str::FromStr;
#[derive(Debug)]
struct NestedParseError {
message: String,
wraps: Option<Box<dyn std::error::Error + 'static>>,
}
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<dyn std::error::Error>) -> 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<T>(input: &str, delimiter: &str) -> Vec<T>
pub fn parse_delimited<T>(input: &str, delimiter: &str) -> Result<Vec<T>, NestedParseError>
where
T: FromStr,
<T as FromStr>::Err: fmt::Debug,
<T as FromStr>::Err: std::error::Error,
{
input
let results: Vec<Result<T, <T as FromStr>::Err>> = input
.split(delimiter)
.map(|v| {
v.trim()
.parse::<T>()
.expect(format!("Unable to parse '{}' from text '{}'", v, input).as_str())
})
.collect()
.map(|v| v.trim().parse::<T>())
.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::<Vec<T>>());
}
}
/// Returns a string with each element of the vector formatted and joined