use std::time::Duration;
#[doc(inline)]
use crate::date::DateTime;
#[doc(inline)]
use crate::entry::Entry;
#[derive(Debug, Clone, Eq, Ord, PartialOrd, PartialEq)]
pub struct TaskEvent {
start: DateTime,
proj: Option<String>,
dur: Duration
}
impl TaskEvent {
pub fn new<'a, OS>(start: DateTime, proj: OS, dur: Duration) -> Self
where
OS: Into<Option<&'a str>>
{
Self { start, proj: proj.into().map(ToString::to_string), dur }
}
pub fn from_entry(entry: &Entry) -> Self {
Self::new(entry.date_time(), entry.project(), Duration::default())
}
#[rustfmt::skip]
pub fn split(&self, dur: Duration) -> Option<(Self, Self)> {
Some((
Self {
start: self.start,
proj: self.proj(),
dur
},
Self {
start: (self.start + dur).ok()?,
proj: self.proj(),
dur: self.dur - dur
}
))
}
pub fn proj(&self) -> Option<String> { self.proj.as_ref().cloned() }
pub fn project(&self) -> String { self.proj().unwrap_or_default() }
pub fn hour(&self) -> usize { self.start.hour() as usize }
pub fn start(&self) -> &DateTime { &self.start }
pub fn add_dur(&mut self, dur: Duration) { self.dur += dur; }
pub fn duration(&self) -> Duration { self.dur }
pub fn as_secs(&self) -> u64 { self.dur.as_secs() }
pub fn second_offset(&self) -> u32 { self.start.second_offset() }
}
#[cfg(test)]
mod tests {
use assert2::{assert, let_assert};
use super::*;
use crate::DateTime;
#[test]
fn test_new_with_project() {
let_assert!(Ok(datetime) = DateTime::new((2022, 3, 20), (12, 34, 56)));
let task = TaskEvent::new(
datetime,
"proja",
Duration::from_secs(305)
);
let_assert!(Some(proj) = task.proj());
assert!(proj == String::from("proja"));
assert!(task.project() == String::from("proja"));
let_assert!(Ok(expect_start) = DateTime::new((2022, 3, 20), (12, 34, 56)));
assert!(task.start() == &expect_start);
assert!(task.hour() == 12);
assert!(task.duration() == Duration::from_secs(305));
}
#[test]
fn test_new_without_project() {
let_assert!(Ok(datetime) = DateTime::new((2022, 3, 20), (13, 24, 56)));
let task = TaskEvent::new(
datetime,
None,
Duration::from_secs(255)
);
assert!(task.proj() == None);
assert!(task.project() == String::new());
let_assert!(Ok(expect_start) = DateTime::new((2022, 3, 20), (13, 24, 56)));
assert!(task.start() == &expect_start);
assert!(task.hour() == 13);
assert!(task.duration() == Duration::from_secs(255));
}
#[test]
fn test_add_dur() {
let_assert!(Ok(datetime) = DateTime::new((2022, 3, 20), (12, 34, 56)));
let mut task = TaskEvent::new(
datetime,
"proja",
Duration::from_secs(305)
);
assert!(task.as_secs() == 305, "Initial value");
task.add_dur(Duration::from_secs(3600));
assert!(task.as_secs() == 3905, "After add_dur");
assert!(task.duration() == Duration::from_secs(3905));
}
#[test]
fn test_second_offset() {
let_assert!(Ok(datetime) = DateTime::new((2022, 3, 20), (12, 34, 56)));
let task = TaskEvent::new(
datetime,
"proja",
Duration::from_secs(305)
);
assert!(task.second_offset() == 34 * 60 + 56);
}
#[test]
fn test_split() {
let_assert!(Ok(datetime) = DateTime::new((2022, 3, 20), (12, 34, 56)));
let task = TaskEvent::new(
datetime,
"proja",
Duration::from_secs(600)
);
let_assert!(Some((first, second)) = task.split(Duration::from_secs(250)));
let_assert!(Ok(expected) = DateTime::new((2022, 3, 20), (12, 34, 56)));
assert!(first.start() == &expected);
assert!(first.duration() == Duration::from_secs(250));
let_assert!(Ok(expected) = DateTime::new((2022, 3, 20), (12, 39, 6)));
assert!(second.start() == &expected);
assert!(second.duration() == Duration::from_secs(350));
}
}