index : git-mirror-sync.git

ascending towards madness

use std::fmt::Display;

use humantime::DurationError;

/// A custom error type for parsing-related errors.
///
/// This error is used throughout the application to represent
/// failures in parsing command line arguments.
#[derive(Debug)]
pub struct ParseError {
    pub message: String,
}

impl ParseError {
    /// Creates a new `ParseError` with the given message.
    ///
    /// # Arguments
    ///
    /// - `message` - A string slice that holds the message for the error.
    pub fn new(message: &str) -> ParseError {
        ParseError {
            message: message.into(),
        }
    }
}

impl Display for ParseError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.message)
    }
}

impl std::error::Error for ParseError {}

impl From<DurationError> for ParseError {
    /// Converts a `humantime::DurationError` into a `ParseError`.
    fn from(value: DurationError) -> Self {
        ParseError::new(&value.to_string())
    }
}

#[cfg(test)]
mod tests {
    use std::time::Duration;

    use super::*;

    #[test]
    fn test_parse_error_new() {
        let error_message = "test error";
        let error = ParseError::new(error_message);
        assert_eq!(error.message, error_message);
    }

    #[test]
    fn test_parse_duration() {
        let good_duration = "35s";
        let bad_duration = "35mi";

        // this should pass
        let first_test = humantime::parse_duration(good_duration).unwrap();
        assert_eq!(first_test, Duration::new(35, 0));

        // this should fail
        let second_test = humantime::parse_duration(bad_duration);
        assert!(second_test.is_err());
    }

    #[test]
    fn test_parse_error_display() {
        let error_message = "display error";
        let error = ParseError::new(error_message);
        assert_eq!(format!("{}", error), error_message);
    }
}