use super::model::*;
use chrono::prelude::*;
use chrono::Duration;
use uuid::Uuid;
fn is_past(a: DateTime<Local>, b: DateTime<Local>) -> bool {
if a.signed_duration_since(b) > Duration::seconds(0) {
return true;
} else {
return false;
}
}
pub struct Blank {done: bool}
impl Blank {
pub fn new() -> Box<Blank> { Box::new(Blank{done: false}) }
}
impl Recur for Blank {
fn current(&self) -> Option<DateTime<Local>> {
return None;
}
fn next(&mut self) -> () {
self.done = true;
}
fn active(&self) -> RecurState {
if self.done {RecurState::Dead} else {RecurState::Active}
}
}
pub struct Deadline {
pub due: DateTime<Local>,
done: bool
}
impl Deadline {
pub fn new(due: DateTime<Local>) -> Box<Deadline> {
Box::new(Deadline {
due,
done: false
})
}
}
impl Recur for Deadline {
fn current(&self) -> Option<DateTime<Local>> {
if !self.done {
Some(self.due)
} else {
None
}
}
fn next(&mut self) -> () {
self.done = true;
}
fn active(&self) -> RecurState {
if self.done {
return RecurState::Dead;
} else {
return RecurState::Active;
}
}
}
pub struct Constant {
pub due: DateTime<Local>,
pub repeat: Duration,
pub end_date: Option<DateTime<Local>>
}
impl Constant {
pub fn new(
due: DateTime<Local>,
end_date: Option<DateTime<Local>>,
repeat: Duration,
) -> Box<Constant> {
Box::new(Constant {
due,
end_date,
repeat,
})
}
}
impl Recur for Constant {
fn current(&self) -> Option<DateTime<Local>> {
if let Some(end_date) = self.end_date {
if is_past(self.due, end_date) {
return None;
}
}
Some(self.due)
}
fn next(&mut self) -> () {
self.due = self.due + self.repeat;
}
fn active(&self) -> RecurState {
if let Some(end_date) = self.end_date {
if is_past(self.due, end_date) {
return RecurState::Dead
}
}
RecurState::Active
}
}
pub struct Date {
pub date: DateTime<Local>
}
impl Date {
pub fn new(date: DateTime<Local>) -> Box<Date> {
Box::new(Date { date })
}
}
impl Dependency for Date {
fn available(&self, _space: &Workspace, _task: &Task) -> Result<bool, TaskError> {
Ok(is_past(Local::now(), self.date))
}
}
pub struct RelativeDate {
pub off: Duration
}
impl RelativeDate {
pub fn new(off: Duration) -> Box<RelativeDate> {
Box::new(RelativeDate { off })
}
}
impl Dependency for RelativeDate {
fn available(&self, _space: &Workspace, task: &Task) -> Result<bool, TaskError> {
let date = task.date.current().ok_or(TaskError::NonexistentError)?; Ok(is_past(Local::now(), date - self.off))
}
}
pub struct Direct {
pub id: Uuid
}
impl Direct {
pub fn new(id: Uuid) -> Box<Direct> {
Box::new(Direct { id })
}
}
impl Dependency for Direct {
fn available(&self, space: &Workspace, _task: &Task) -> Result<bool, TaskError> {
let dep = space.tasks.get(&self.id).ok_or(TaskError::NonexistentError)?;
Ok(dep.date.active() == RecurState::Dead)
}
}