From 3c3637b674e648649842b141a16a0f56c5ef95cc Mon Sep 17 00:00:00 2001 From: Jonathan Turner Date: Sat, 16 Nov 2019 14:36:51 +1300 Subject: [PATCH] Add comparison between dates --- src/data/base.rs | 3 + .../hir/syntax_shape/expression/unit.rs | 19 ++- src/parser/parse/unit.rs | 110 +++++++++++++----- 3 files changed, 100 insertions(+), 32 deletions(-) diff --git a/src/data/base.rs b/src/data/base.rs index f0357273e..4baa8f1d6 100644 --- a/src/data/base.rs +++ b/src/data/base.rs @@ -856,6 +856,7 @@ enum CompareValues { Ints(BigInt, BigInt), Decimals(BigDecimal, BigDecimal), String(String, String), + Date(DateTime, DateTime), } impl CompareValues { @@ -864,6 +865,7 @@ impl CompareValues { CompareValues::Ints(left, right) => left.cmp(right), CompareValues::Decimals(left, right) => left.cmp(right), CompareValues::String(left, right) => left.cmp(right), + CompareValues::Date(left, right) => right.cmp(left), } } } @@ -900,6 +902,7 @@ fn coerce_compare_primitive( CompareValues::Decimals(BigDecimal::from(*left), right.clone()) } (String(left), String(right)) => CompareValues::String(left.clone(), right.clone()), + (Date(left), Date(right)) => CompareValues::Date(left.clone(), right.clone()), _ => return Err((left.type_name(), right.type_name())), }) } diff --git a/src/parser/hir/syntax_shape/expression/unit.rs b/src/parser/hir/syntax_shape/expression/unit.rs index c4bd85434..901b86e8d 100644 --- a/src/parser/hir/syntax_shape/expression/unit.rs +++ b/src/parser/hir/syntax_shape/expression/unit.rs @@ -86,12 +86,19 @@ fn unit_size(input: &str, bare_span: Span) -> IResult<&str, (Spanned, }; let (input, unit) = all_consuming(alt(( - value(Unit::B, alt((tag("B"), tag("b")))), - value(Unit::KB, alt((tag("KB"), tag("kb"), tag("Kb")))), - value(Unit::MB, alt((tag("MB"), tag("mb"), tag("Mb")))), - value(Unit::GB, alt((tag("GB"), tag("gb"), tag("Gb")))), - value(Unit::TB, alt((tag("TB"), tag("tb"), tag("Tb")))), - value(Unit::PB, alt((tag("PB"), tag("pb"), tag("Pb")))), + value(Unit::Byte, alt((tag("B"), tag("b")))), + value(Unit::Kilobyte, alt((tag("KB"), tag("kb"), tag("Kb")))), + value(Unit::Megabyte, alt((tag("MB"), tag("mb"), tag("Mb")))), + value(Unit::Gigabyte, alt((tag("GB"), tag("gb"), tag("Gb")))), + value(Unit::Terabyte, alt((tag("TB"), tag("tb"), tag("Tb")))), + value(Unit::Petabyte, alt((tag("PB"), tag("pb"), tag("Pb")))), + value(Unit::Second, tag("s")), + value(Unit::Minute, tag("m")), + value(Unit::Hour, tag("h")), + value(Unit::Day, tag("d")), + value(Unit::Week, tag("w")), + value(Unit::Month, tag("M")), + value(Unit::Year, tag("y")), )))(input)?; let start_span = number.span.end(); diff --git a/src/parser/parse/unit.rs b/src/parser/parse/unit.rs index e2075636a..e98a5cdbc 100644 --- a/src/parser/parse/unit.rs +++ b/src/parser/parse/unit.rs @@ -3,15 +3,34 @@ use crate::prelude::*; use serde::{Deserialize, Serialize}; use std::fmt; use std::str::FromStr; +use std::time::Duration; +use std::time::SystemTime; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] pub enum Unit { - B, - KB, - MB, - GB, - TB, - PB, + // Filesize units + Byte, + Kilobyte, + Megabyte, + Gigabyte, + Terabyte, + Petabyte, + + // Duration units + Second, + Minute, + Hour, + Day, + Week, + Month, + Year, +} + +fn convert_number_to_u64(number: &Number) -> u64 { + match number { + Number::Int(big_int) => big_int.to_u64().unwrap(), + Number::Decimal(big_decimal) => big_decimal.to_u64().unwrap(), + } } impl FormatDebug for Spanned { @@ -23,26 +42,58 @@ impl FormatDebug for Spanned { impl Unit { pub fn as_str(&self) -> &str { match *self { - Unit::B => "B", - Unit::KB => "KB", - Unit::MB => "MB", - Unit::GB => "GB", - Unit::TB => "TB", - Unit::PB => "PB", + Unit::Byte => "B", + Unit::Kilobyte => "KB", + Unit::Megabyte => "MB", + Unit::Gigabyte => "GB", + Unit::Terabyte => "TB", + Unit::Petabyte => "PB", + Unit::Second => "s", + Unit::Minute => "m", + Unit::Hour => "h", + Unit::Day => "d", + Unit::Week => "w", + Unit::Month => "M", + Unit::Year => "y", } } pub(crate) fn compute(&self, size: &Number) -> Value { let size = size.clone(); - Value::number(match self { - Unit::B => size, - Unit::KB => size * 1024, - Unit::MB => size * 1024 * 1024, - Unit::GB => size * 1024 * 1024 * 1024, - Unit::TB => size * 1024 * 1024 * 1024 * 1024, - Unit::PB => size * 1024 * 1024 * 1024 * 1024 * 1024, - }) + match self { + Unit::Byte => Value::number(size), + Unit::Kilobyte => Value::number(size * 1024), + Unit::Megabyte => Value::number(size * 1024 * 1024), + Unit::Gigabyte => Value::number(size * 1024 * 1024 * 1024), + Unit::Terabyte => Value::number(size * 1024 * 1024 * 1024 * 1024), + Unit::Petabyte => Value::number(size * 1024 * 1024 * 1024 * 1024 * 1024), + Unit::Second => Value::system_date( + SystemTime::now() - Duration::from_secs(convert_number_to_u64(&size)), + ), + Unit::Minute => Value::system_date( + SystemTime::now() - Duration::from_secs(60 * convert_number_to_u64(&size)), + ), + Unit::Hour => Value::system_date( + SystemTime::now() - Duration::from_secs(60 * 60 * convert_number_to_u64(&size)), + ), + Unit::Day => Value::system_date( + SystemTime::now() + - Duration::from_secs(24 * 60 * 60 * convert_number_to_u64(&size)), + ), + Unit::Week => Value::system_date( + SystemTime::now() + - Duration::from_secs(7 * 24 * 60 * 60 * convert_number_to_u64(&size)), + ), + Unit::Month => Value::system_date( + SystemTime::now() + - Duration::from_secs(30 * 24 * 60 * 60 * convert_number_to_u64(&size)), + ), + Unit::Year => Value::system_date( + SystemTime::now() + - Duration::from_secs(365 * 24 * 60 * 60 * convert_number_to_u64(&size)), + ), + } } } @@ -50,12 +101,19 @@ impl FromStr for Unit { type Err = (); fn from_str(input: &str) -> Result::Err> { match input { - "B" | "b" => Ok(Unit::B), - "KB" | "kb" | "Kb" | "K" | "k" => Ok(Unit::KB), - "MB" | "mb" | "Mb" => Ok(Unit::MB), - "GB" | "gb" | "Gb" => Ok(Unit::GB), - "TB" | "tb" | "Tb" => Ok(Unit::TB), - "PB" | "pb" | "Pb" => Ok(Unit::PB), + "B" | "b" => Ok(Unit::Byte), + "KB" | "kb" | "Kb" | "K" | "k" => Ok(Unit::Kilobyte), + "MB" | "mb" | "Mb" => Ok(Unit::Megabyte), + "GB" | "gb" | "Gb" => Ok(Unit::Gigabyte), + "TB" | "tb" | "Tb" => Ok(Unit::Terabyte), + "PB" | "pb" | "Pb" => Ok(Unit::Petabyte), + "s" => Ok(Unit::Second), + "m" => Ok(Unit::Minute), + "h" => Ok(Unit::Hour), + "d" => Ok(Unit::Day), + "w" => Ok(Unit::Week), + "M" => Ok(Unit::Month), + "y" => Ok(Unit::Year), _ => Err(()), } }