66 lines
1.6 KiB
Rust
66 lines
1.6 KiB
Rust
use chrono::{Datelike, Duration, Months, NaiveDate, Weekday};
|
|
|
|
#[derive(Debug)]
|
|
pub struct CalendarRow {
|
|
pub begin: NaiveDate,
|
|
pub end: NaiveDate,
|
|
}
|
|
|
|
pub enum RowDay {
|
|
InRange(NaiveDate),
|
|
NotInRange(NaiveDate),
|
|
}
|
|
|
|
impl RowDay {
|
|
pub fn new(row: &CalendarRow, day: NaiveDate) -> RowDay {
|
|
if day >= row.begin && day < row.end {
|
|
RowDay::InRange(day)
|
|
} else {
|
|
RowDay::NotInRange(day)
|
|
}
|
|
}
|
|
|
|
pub fn day(self) -> NaiveDate {
|
|
match self {
|
|
Self::InRange(day) => day,
|
|
Self::NotInRange(day) => day,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// A row in the calendar.
|
|
///
|
|
/// The row is always aligned to a week, i.e. the first
|
|
/// day of the row is the first day of the week (for now always Monday)
|
|
impl CalendarRow {
|
|
/// A row that spans the month containing the given day
|
|
pub fn for_month(day: NaiveDate) -> CalendarRow {
|
|
let begin = day.with_day0(0).unwrap();
|
|
CalendarRow {
|
|
begin,
|
|
end: begin + Months::new(1),
|
|
}
|
|
}
|
|
|
|
/// A row that spans the week containing the given day
|
|
pub fn for_week(day: NaiveDate) -> CalendarRow {
|
|
let begin = day.week(Weekday::Mon).first_day();
|
|
CalendarRow {
|
|
begin,
|
|
end: begin + Duration::weeks(1),
|
|
}
|
|
}
|
|
|
|
/// Get the day for the given column of the row
|
|
pub fn date_for_col(self: &Self, col: i64) -> RowDay {
|
|
RowDay::new(
|
|
self,
|
|
self.begin.week(Weekday::Mon).first_day() + Duration::days(col),
|
|
)
|
|
}
|
|
|
|
pub fn num_days(&self) -> i64 {
|
|
(self.end - self.begin).num_days()
|
|
}
|
|
}
|