//! The module for the TimeType
//!
use chrono::NaiveDateTime;
use std::ops::Add;
use std::ops::Sub;
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 Sub for TimeType {
type Output = TimeType;
fn sub(self, rhs: TimeType) -> Self::Output {
TimeType::Subtraction(Box::new(self), 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 seconds(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::seconds(i))
}
pub fn minutes(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::minutes(i))
}
pub fn hours(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::hours(i))
}
pub fn days(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::days(i))
}
pub fn weeks(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::weeks(i))
}
pub fn months(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::weeks(i * 4))
}
pub fn years(i: i64) -> TimeType {
TimeType::Duration(::chrono::Duration::weeks(i * 4 * 12))
}
pub fn moment(ndt: NaiveDateTime) -> TimeType {
TimeType::Moment(ndt)
}
/// Get the number of seconds, if the TimeType is not a duration type, zero is returned
pub fn get_seconds(&self) -> i64 {
match *self {
TimeType::Duration(d) => d.num_seconds(),
_ => 0
}
}
/// Get the number of minutes, if the TimeType is not a duration type, zero is returned
pub fn get_minutes(&self) -> i64 {
match *self {
TimeType::Duration(d) => d.num_minutes(),
_ => 0,
}
}
/// Get the number of hours, if the TimeType is not a duration type, zero is returned
pub fn get_hours(&self) -> i64 {
match *self {
TimeType::Duration(d) => d.num_hours(),
_ => 0,
}
}
/// Get the number of days, if the TimeType is not a duration type, zero is returned
pub fn get_days(&self) -> i64