///|
fn checked(value : Int, lower : Int, upper : Int) -> Result[Int, CronError] {
if value >= lower && value <= upper {
Ok(value)
} else {
Err(ValueOutOfRange(value.to_string(), lower, upper))
}
}
///|
/// A schedule that fires every minute.
pub fn every_minute() -> Cron {
{ minute: Any, hour: Any, day_of_month: Any, month: Any, weekday: Any }
}
///|
/// A schedule that fires once a day at the given wall-clock time.
pub fn daily_at(hour : Int, minute : Int) -> Result[Cron, CronError] {
match (checked(hour, 0, 23), checked(minute, 0, 59)) {
(Ok(hour), Ok(minute)) =>
Ok({
minute: Exact(minute),
hour: Exact(hour),
day_of_month: Any,
month: Any,
weekday: Any,
})
(Err(error), _) => Err(error)
(_, Err(error)) => Err(error)
}
}
///|
/// A schedule that fires once a week. The weekday accepts 0 through 7;
/// both 0 and 7 mean Sunday and are stored canonically as 0.
pub fn weekly_on(
weekday : Int,
hour : Int,
minute : Int,
) -> Result[Cron, CronError] {
match (checked(weekday, 0, 7), checked(hour, 0, 23), checked(minute, 0, 59)) {
(Ok(weekday), Ok(hour), Ok(minute)) => {
let canonical = if weekday == 7 { 0 } else { weekday }
Ok({
minute: Exact(minute),
hour: Exact(hour),
day_of_month: Any,
month: Any,
weekday: Exact(canonical),
})
}
(Err(error), _, _) => Err(error)
(_, Err(error), _) => Err(error)
(_, _, Err(error)) => Err(error)
}
}
///|
/// A schedule that fires once a month on the given day. Days 29 through
/// 31 simply skip months that are too short, as in standard cron.
pub fn monthly_on(
day : Int,
hour : Int,
minute : Int,
) -> Result[Cron, CronError] {
match (checked(day, 1, 31), checked(hour, 0, 23), checked(minute, 0, 59)) {
(Ok(day), Ok(hour), Ok(minute)) =>
Ok({
minute: Exact(minute),
hour: Exact(hour),
day_of_month: Exact(day),
month: Any,
weekday: Any,
})
(Err(error), _, _) => Err(error)
(_, Err(error), _) => Err(error)
(_, _, Err(error)) => Err(error)
}
}