recurring_event 0.1.3

Calculate dates for recurring events (daily, weekly, monthly and yearly).
Documentation
use time::{Duration, Month, OffsetDateTime};
use crate::error::Error;

pub fn first_date_of_month(current_date: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
    let date = current_date.replace_day(1)?;
    Ok(date)
}

pub fn first_date_of_next_month(current_date: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
    let mut date = *current_date;
    date = date.replace_day(1)?;
    date = date.replace_month(date.month().next())?;
    if date.month() == Month::January {
        date = date.replace_year(date.year() +1)?;
    }
    Ok(date)
}

pub fn first_date_of_next_week(current_date: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
    let mut date = *current_date;
    date = date.checked_add(Duration::days(7)).unwrap();
    first_date_of_week(&date)
}

pub fn first_date_of_next_year(current_date: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
    let date = *current_date;
    Ok(date.replace_day(1)?.replace_month(Month::January)?.replace_year(current_date.year() + 1)?)
}

pub fn first_date_of_week(current_date: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
    let number_days_from_monday = current_date.weekday().number_days_from_monday();
    let date = current_date.checked_sub(Duration::days(number_days_from_monday as i64)).ok_or(Error::DateOverflow)?.date();
    Ok(current_date.replace_date(date))
}

pub fn months_later(current_date: &OffsetDateTime, number_of_month: u16) -> Result<OffsetDateTime, Error> {
    let mut date = *current_date;
    let mut times = 0;

    while times < number_of_month {
        date = date.replace_month(date.month().next())?;
        if date.month() == Month::January {
            date = date.replace_year(date.year() +1)?;
        }
        times += 1;
    };
    Ok(date)
}

pub fn next_day(current_date: &OffsetDateTime) -> Result<OffsetDateTime, Error> {
    current_date.checked_add(Duration::days(1)).ok_or(Error::DateOverflow)
}