Unify Dates logic and expand DoneDate format
This commit is contained in:
parent
2e7ab3c4a1
commit
c69af9bcde
8 changed files with 119 additions and 133 deletions
178
src/eval/date.rs
178
src/eval/date.rs
|
|
@ -20,44 +20,8 @@ pub struct Dates {
|
|||
|
||||
impl fmt::Display for Dates {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let (start, end) = self.start_end();
|
||||
match self.start_end_time() {
|
||||
Some((start_time, end_time)) if start == end && start_time == end_time => {
|
||||
write!(f, "{} {}", start, start_time)
|
||||
}
|
||||
Some((start_time, end_time)) if start == end => {
|
||||
write!(f, "{} {} -- {}", start, start_time, end_time)
|
||||
}
|
||||
Some((start_time, end_time)) => {
|
||||
write!(f, "{} {} -- {} {}", start, start_time, end, end_time)
|
||||
}
|
||||
None if start == end => write!(f, "{}", start),
|
||||
None => write!(f, "{} -- {}", start, end),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Dates> for DoneDate {
|
||||
fn from(dates: Dates) -> Self {
|
||||
match dates.times {
|
||||
Some(times) if dates.root == dates.other && times.root == times.other => {
|
||||
DoneDate::DateWithTime {
|
||||
root: dates.root,
|
||||
root_time: times.root,
|
||||
}
|
||||
}
|
||||
Some(times) => DoneDate::DateToDateWithTime {
|
||||
root: dates.root,
|
||||
root_time: times.root,
|
||||
other: dates.other,
|
||||
other_time: times.other,
|
||||
},
|
||||
None if dates.root == dates.other => DoneDate::Date { root: dates.root },
|
||||
None => DoneDate::DateToDate {
|
||||
root: dates.root,
|
||||
other: dates.other,
|
||||
},
|
||||
}
|
||||
let done_date: DoneDate = (*self).into();
|
||||
write!(f, "{}", done_date)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,66 +50,55 @@ impl Dates {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn root(&self) -> NaiveDate {
|
||||
pub fn root(self) -> NaiveDate {
|
||||
self.root
|
||||
}
|
||||
|
||||
pub fn other(&self) -> NaiveDate {
|
||||
self.other
|
||||
pub fn root_with_time(self) -> (NaiveDate, Option<Time>) {
|
||||
(self.root, self.times.map(|t| t.root))
|
||||
}
|
||||
|
||||
pub fn root_time(&self) -> Option<Time> {
|
||||
self.times.map(|times| times.root)
|
||||
pub fn other_with_time(self) -> (NaiveDate, Option<Time>) {
|
||||
(self.other, self.times.map(|t| t.other))
|
||||
}
|
||||
|
||||
pub fn other_time(&self) -> Option<Time> {
|
||||
self.times.map(|times| times.other)
|
||||
pub fn dates(self) -> (NaiveDate, NaiveDate) {
|
||||
(self.root, self.other)
|
||||
}
|
||||
|
||||
pub fn start_end(&self) -> (NaiveDate, NaiveDate) {
|
||||
if self.root <= self.other {
|
||||
(self.root, self.other)
|
||||
} else {
|
||||
(self.other, self.root)
|
||||
pub fn times(self) -> Option<(Time, Time)> {
|
||||
self.times.map(|times| (times.root, times.other))
|
||||
}
|
||||
|
||||
/// Flip `root` and `other`.
|
||||
fn flip(self) -> Self {
|
||||
Self {
|
||||
root: self.other,
|
||||
other: self.root,
|
||||
times: self.times.map(|times| Times {
|
||||
root: times.other,
|
||||
other: times.root,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&self) -> NaiveDate {
|
||||
self.start_end().0
|
||||
}
|
||||
|
||||
pub fn end(&self) -> NaiveDate {
|
||||
self.start_end().1
|
||||
}
|
||||
|
||||
pub fn start_end_time(&self) -> Option<(Time, Time)> {
|
||||
if let Some(times) = self.times {
|
||||
if self.root < self.other || (self.root == self.other && times.root <= times.other) {
|
||||
Some((times.root, times.other))
|
||||
} else {
|
||||
Some((times.other, times.root))
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_time(&self) -> Option<Time> {
|
||||
self.start_end_time().map(|times| times.0)
|
||||
}
|
||||
|
||||
pub fn end_time(&self) -> Option<Time> {
|
||||
self.start_end_time().map(|times| times.1)
|
||||
}
|
||||
|
||||
pub fn point_in_time(&self) -> Option<(NaiveDate, Option<Time>)> {
|
||||
if self.root != self.other {
|
||||
return None;
|
||||
}
|
||||
/// Return a new [`Dates`] where `root` is the earlier and `other` the later
|
||||
/// date.
|
||||
pub fn sorted(self) -> Self {
|
||||
match self.times {
|
||||
Some(times) if times.root == times.other => Some((self.root, Some(times.root))),
|
||||
Some(_) => None,
|
||||
None => Some((self.root, None)),
|
||||
_ if self.root < self.other => self,
|
||||
None if self.root <= self.other => self,
|
||||
Some(times) if self.root <= self.other && times.root <= times.other => self,
|
||||
_ => self.flip(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn point_in_time(self) -> Option<(NaiveDate, Option<Time>)> {
|
||||
let done_date: DoneDate = self.into();
|
||||
match done_date {
|
||||
DoneDate::Date { root } => Some((root, None)),
|
||||
DoneDate::DateTime { root, root_time } => Some((root, Some(root_time))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -162,27 +115,52 @@ impl From<DoneDate> for Dates {
|
|||
fn from(date: DoneDate) -> Self {
|
||||
match date {
|
||||
DoneDate::Date { root } => Self::new(root, root),
|
||||
DoneDate::DateWithTime { root, root_time } => {
|
||||
DoneDate::DateTime { root, root_time } => {
|
||||
Self::new_with_time(root, root_time, root, root_time)
|
||||
}
|
||||
DoneDate::DateToDate { root, other } => {
|
||||
if root <= other {
|
||||
Self::new(root, other)
|
||||
} else {
|
||||
Self::new(other, root)
|
||||
}
|
||||
}
|
||||
DoneDate::DateToDateWithTime {
|
||||
DoneDate::DateToDate { root, other } => Self::new(root, other),
|
||||
DoneDate::DateTimeToTime {
|
||||
root,
|
||||
root_time,
|
||||
other_time,
|
||||
} => Self::new_with_time(root, root_time, root, other_time),
|
||||
DoneDate::DateTimeToDateTime {
|
||||
root,
|
||||
root_time,
|
||||
other,
|
||||
other_time,
|
||||
} => {
|
||||
if root < other || (root == other && root_time <= other_time) {
|
||||
Self::new_with_time(root, root_time, other, other_time)
|
||||
} else {
|
||||
Self::new_with_time(other, other_time, root, root_time)
|
||||
}
|
||||
} => Self::new_with_time(root, root_time, other, other_time),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Dates> for DoneDate {
|
||||
fn from(dates: Dates) -> Self {
|
||||
if dates.root == dates.other {
|
||||
match dates.times {
|
||||
Some(times) if times.root == times.other => Self::DateTime {
|
||||
root: dates.root,
|
||||
root_time: times.root,
|
||||
},
|
||||
Some(times) => Self::DateTimeToTime {
|
||||
root: dates.root,
|
||||
root_time: times.root,
|
||||
other_time: times.other,
|
||||
},
|
||||
None => Self::Date { root: dates.root },
|
||||
}
|
||||
} else {
|
||||
match dates.times {
|
||||
Some(times) => Self::DateTimeToDateTime {
|
||||
root: dates.root,
|
||||
root_time: times.root,
|
||||
other: dates.other,
|
||||
other_time: times.other,
|
||||
},
|
||||
None => Self::DateToDate {
|
||||
root: dates.root,
|
||||
other: dates.other,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,9 @@ impl Entries {
|
|||
|
||||
fn is_touching(&self, entry: &Entry) -> bool {
|
||||
if let Some(dates) = entry.dates {
|
||||
let (start, end) = dates.sorted().dates();
|
||||
// Inside the range or overlapping it
|
||||
dates.start() <= self.range.until() && self.range.from() <= dates.end()
|
||||
start <= self.range.until() && self.range.from() <= end
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
@ -102,7 +103,8 @@ impl Entries {
|
|||
// Unfinished tasks before or inside the range
|
||||
if let EntryKind::Task = entry.kind {
|
||||
if let Some(dates) = entry.dates {
|
||||
if dates.start() <= self.range.until() {
|
||||
let (start, _) = dates.sorted().dates();
|
||||
if start <= self.range.until() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue