rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use super::TaskId;
use thiserror::Error;

#[derive(Debug, Clone, PartialEq, Eq, Error)]
pub enum TaskError {
    #[error("task id must not be blank")]
    InvalidTaskId,
    #[error("task name must not be blank")]
    InvalidTaskName,
    #[error("invalid schedule: {0}")]
    InvalidSchedule(String),
    #[error("task result for '{0}' was not found")]
    ResultNotFound(TaskId),
}

impl TaskError {
    #[must_use]
    pub fn is_validation_error(&self) -> bool {
        matches!(
            self,
            Self::InvalidTaskId | Self::InvalidTaskName | Self::InvalidSchedule(_)
        )
    }
}

#[cfg(test)]
mod tests {
    use super::TaskError;
    use std::error::Error as StdError;

    #[test]
    fn invalid_task_id_has_honest_message() {
        assert_eq!(
            TaskError::InvalidTaskId.to_string(),
            "task id must not be blank"
        );
    }

    #[test]
    fn invalid_schedule_is_marked_as_validation_error() {
        let error = TaskError::InvalidSchedule("minute field must not be empty".to_string());

        assert!(error.is_validation_error());
        assert_eq!(
            error.to_string(),
            "invalid schedule: minute field must not be empty"
        );
    }

    #[test]
    fn result_not_found_is_not_a_validation_error() {
        let error = TaskError::ResultNotFound("task-42".to_string());

        assert!(!error.is_validation_error());
        assert_eq!(error.to_string(), "task result for 'task-42' was not found");
    }

    #[test]
    fn task_error_implements_std_error() {
        let error = TaskError::InvalidTaskName;
        let dyn_error: &dyn StdError = &error;

        assert_eq!(dyn_error.to_string(), "task name must not be blank");
    }
}