cron-expr 0.1.0

Cron expression parsing and evaluation
Documentation
use std::fmt;
use std::fmt::Formatter;

use crate::time_unit::TimeUnitKind;

#[derive(Debug)]
pub enum TimeUnitErrorKind<'a> {
    InvalidValue,
    InvalidRange,
    InvalidRangeStart(Box<TimeUnitError<'a>>),
    InvalidRangeEnd(Box<TimeUnitError<'a>>),
    InvalidStep,
    OutOfBounds
}

impl<'a> TimeUnitErrorKind<'a> {
    pub fn err(self, value: &'a str) -> TimeUnitError<'a> {
        TimeUnitError {
            input: value,
            kind: self
        }
    }
}

#[derive(Debug)]
pub struct TimeUnitError<'a> {
    input: &'a str,
    kind: TimeUnitErrorKind<'a>
}

impl<'a> std::error::Error for TimeUnitError<'a> {}

impl<'a> fmt::Display for TimeUnitError<'a> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        use TimeUnitErrorKind::*;

        write!(f, "`{}`: ", self.input)?;

        match &self.kind {
            InvalidValue => write!(f, "invalid value"),
            InvalidRange => write!(f, "invalid range"),
            InvalidRangeStart(cause) => write!(f, "invalid range start value => {}", cause),
            InvalidRangeEnd(cause) => write!(f, "invalid range end value => {}", cause),
            InvalidStep => write!(f, "invalid step"),
            OutOfBounds => write!(f, "out of bounds")
        }?;

        Ok(())
    }
}

#[derive(Debug)]
pub enum CronErrorKind<'a> {
    InvalidSyntax,
    InvalidTimeUnit(TimeUnitKind, TimeUnitError<'a>)
}

impl<'a> CronErrorKind<'a> {
    pub fn err(self, input: &'a str) -> CronError<'a> {
        CronError {
            input,
            kind: self
        }
    }
}

#[derive(Debug)]
pub struct CronError<'a> {
    input: &'a str,
    kind: CronErrorKind<'a>
}

impl<'a> std::error::Error for CronError<'a> {}

impl<'a> fmt::Display for CronError<'a> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        use CronErrorKind::*;

        write!(f, "`{}`: ", self.input)?;

        match &self.kind {
            InvalidSyntax => write!(f, "invalid cron syntax"),
            InvalidTimeUnit(kind, err) => write!(f, "invalid {} => {}", kind, err),
        }?;

        Ok(())
    }
}