Implement DATE statement
This commit is contained in:
parent
85d2c4bf89
commit
4c83df76d4
6 changed files with 159 additions and 11 deletions
|
|
@ -1,6 +1,9 @@
|
|||
use std::cmp;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use chrono::{Datelike, NaiveDate};
|
||||
use chrono::{Datelike, Duration, NaiveDate};
|
||||
|
||||
use super::delta::Delta;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DateRange {
|
||||
|
|
@ -9,9 +12,20 @@ pub struct DateRange {
|
|||
}
|
||||
|
||||
impl DateRange {
|
||||
pub fn new(from: NaiveDate, until: NaiveDate) -> Self {
|
||||
assert!(from <= until);
|
||||
Self { from, until }
|
||||
pub fn new(from: NaiveDate, until: NaiveDate) -> Option<Self> {
|
||||
if from <= until {
|
||||
Some(Self { from, until })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_from(&self, from: NaiveDate) -> Option<Self> {
|
||||
Self::new(from, self.until)
|
||||
}
|
||||
|
||||
pub fn with_until(&self, until: NaiveDate) -> Option<Self> {
|
||||
Self::new(self.from, until)
|
||||
}
|
||||
|
||||
pub fn contains(&self, date: NaiveDate) -> bool {
|
||||
|
|
@ -29,4 +43,33 @@ impl DateRange {
|
|||
pub fn years(&self) -> RangeInclusive<i32> {
|
||||
self.from.year()..=self.until.year()
|
||||
}
|
||||
|
||||
/// Expand the range so that it contains at least all dates from which the
|
||||
/// original range could be reached using `delta`. This new range will
|
||||
/// always contain the old range.
|
||||
pub fn expand_by(&self, delta: &Delta) -> Self {
|
||||
let expand_lower = cmp::min(-delta.upper_bound(), 0);
|
||||
let expand_upper = cmp::max(-delta.lower_bound(), 0);
|
||||
Self::new(
|
||||
self.from + Duration::days(expand_lower.into()),
|
||||
self.until + Duration::days(expand_upper.into()),
|
||||
)
|
||||
// The range is never shrunk, so the new range should always be valid.
|
||||
.expect("expanded range shrunk")
|
||||
}
|
||||
|
||||
/// Return a new range that contains at least all dates from which the
|
||||
/// original range could be reached using `delta`. This new range might not
|
||||
/// contain the old range.
|
||||
pub fn move_by(&self, delta: &Delta) -> Self {
|
||||
let move_lower = -delta.upper_bound();
|
||||
let move_upper = -delta.lower_bound();
|
||||
Self::new(
|
||||
self.from + Duration::days(move_lower.into()),
|
||||
self.until + Duration::days(move_upper.into()),
|
||||
)
|
||||
// The delta's upper bound is greater or equal than its lower bound, so
|
||||
// the range should never become smaller. It can only move and expand.
|
||||
.expect("moved range shrunk")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue