//! The module for the TimeType
//!
use chrono::NaiveDateTime;
use std::ops::Add;
use std::ops::AddAssign;
use std::ops::Sub;
use std::ops::SubAssign;
use result::Result;
use error::KairosErrorKind as KEK;
use error::KairosError as KE;
use error_chain::ChainedError;
/// A Type of Time, currently based on chrono::NaiveDateTime
#[derive(Debug, Clone)]
pub enum TimeType {
Duration(::chrono::Duration),
Moment(NaiveDateTime),
Addition(Box<TimeType>, Box<TimeType>),
Subtraction(Box<TimeType>, Box<TimeType>),
}
impl Add for TimeType {
type Output = TimeType;
fn add(self, rhs: TimeType) -> Self::Output {
TimeType::Addition(Box::new(self), Box::new(rhs))
}
}
impl AddAssign for TimeType {
fn add_assign(&mut self, rhs: TimeType) {
*self = TimeType::Addition(Box::new(self.clone()), Box::new(rhs));
}
}
impl Sub for TimeType {
type Output = TimeType;
fn sub(self, rhs: TimeType) -> Self::Output {
TimeType::Subtraction(Box::new(self), Box::new(rhs))
}
}
impl SubAssign for TimeType {
fn sub_assign(&mut self, rhs: TimeType) {
*self = TimeType::Subtraction(Box::new(self.clone()), Box::new(rhs));
}
}
/// The TimeType type
///
/// # Warning
///
/// If the TimeType is _larger_ than the queried type (E.G. querying a "minutes" on a "month"),
/// the following rules are applied:
///
/// * 60 Seconds make a Minute
/// * 60 Minutes make a Hour
/// * 24 Hours make a Day
/// * 7 Days make a Week
/// * 4 Weeks make a Month
/// * 12 Months make a Year
///
/// Whether these may be correct or not in the current year. The return value of the function
/// is calculated appropriately. So, calling the `get_seconds()` function on 5 minutes returns
/// `60 * 5`.
///
/// If the TimeType is _smaller_ than the queried type (E.G. querying a "month" on a
/// "minutes"), zero is returned.
///
/// Also, if the TimeType is "5 weeks", querying a month returns `1`, as 5 weeks contain one
/// full month.
///
impl TimeType {
pub fn is_a_amount(&self) -> bool {
match *self {
TimeType::Duration(_) => true,
_ => false,
}
}
pub fn is_moment(&self) -> bool {
match *self {
TimeType::Moment(_) => true,
_ => false,
}
}
pub fn is_addition(&self) -> bool {
match *self {
TimeType::Addition(_, _) => true,
_ => false,
}
}
pub fn is_subtraction(&self) -> bool {
match *self {
TimeType::Subtraction(_