Add comparison between dates

This commit is contained in:
Jonathan Turner 2019-11-16 14:36:51 +13:00
parent bcecd08825
commit 3c3637b674
3 changed files with 100 additions and 32 deletions

View File

@ -856,6 +856,7 @@ enum CompareValues {
Ints(BigInt, BigInt), Ints(BigInt, BigInt),
Decimals(BigDecimal, BigDecimal), Decimals(BigDecimal, BigDecimal),
String(String, String), String(String, String),
Date(DateTime<Utc>, DateTime<Utc>),
} }
impl CompareValues { impl CompareValues {
@ -864,6 +865,7 @@ impl CompareValues {
CompareValues::Ints(left, right) => left.cmp(right), CompareValues::Ints(left, right) => left.cmp(right),
CompareValues::Decimals(left, right) => left.cmp(right), CompareValues::Decimals(left, right) => left.cmp(right),
CompareValues::String(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()) CompareValues::Decimals(BigDecimal::from(*left), right.clone())
} }
(String(left), String(right)) => CompareValues::String(left.clone(), 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())), _ => return Err((left.type_name(), right.type_name())),
}) })
} }

View File

@ -86,12 +86,19 @@ fn unit_size(input: &str, bare_span: Span) -> IResult<&str, (Spanned<RawNumber>,
}; };
let (input, unit) = all_consuming(alt(( let (input, unit) = all_consuming(alt((
value(Unit::B, alt((tag("B"), tag("b")))), value(Unit::Byte, alt((tag("B"), tag("b")))),
value(Unit::KB, alt((tag("KB"), tag("kb"), tag("Kb")))), value(Unit::Kilobyte, alt((tag("KB"), tag("kb"), tag("Kb")))),
value(Unit::MB, alt((tag("MB"), tag("mb"), tag("Mb")))), value(Unit::Megabyte, alt((tag("MB"), tag("mb"), tag("Mb")))),
value(Unit::GB, alt((tag("GB"), tag("gb"), tag("Gb")))), value(Unit::Gigabyte, alt((tag("GB"), tag("gb"), tag("Gb")))),
value(Unit::TB, alt((tag("TB"), tag("tb"), tag("Tb")))), value(Unit::Terabyte, alt((tag("TB"), tag("tb"), tag("Tb")))),
value(Unit::PB, alt((tag("PB"), tag("pb"), tag("Pb")))), 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)?; )))(input)?;
let start_span = number.span.end(); let start_span = number.span.end();

View File

@ -3,15 +3,34 @@ use crate::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration;
use std::time::SystemTime;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
pub enum Unit { pub enum Unit {
B, // Filesize units
KB, Byte,
MB, Kilobyte,
GB, Megabyte,
TB, Gigabyte,
PB, 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<Unit> { impl FormatDebug for Spanned<Unit> {
@ -23,26 +42,58 @@ impl FormatDebug for Spanned<Unit> {
impl Unit { impl Unit {
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
match *self { match *self {
Unit::B => "B", Unit::Byte => "B",
Unit::KB => "KB", Unit::Kilobyte => "KB",
Unit::MB => "MB", Unit::Megabyte => "MB",
Unit::GB => "GB", Unit::Gigabyte => "GB",
Unit::TB => "TB", Unit::Terabyte => "TB",
Unit::PB => "PB", 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 { pub(crate) fn compute(&self, size: &Number) -> Value {
let size = size.clone(); let size = size.clone();
Value::number(match self { match self {
Unit::B => size, Unit::Byte => Value::number(size),
Unit::KB => size * 1024, Unit::Kilobyte => Value::number(size * 1024),
Unit::MB => size * 1024 * 1024, Unit::Megabyte => Value::number(size * 1024 * 1024),
Unit::GB => size * 1024 * 1024 * 1024, Unit::Gigabyte => Value::number(size * 1024 * 1024 * 1024),
Unit::TB => size * 1024 * 1024 * 1024 * 1024, Unit::Terabyte => Value::number(size * 1024 * 1024 * 1024 * 1024),
Unit::PB => size * 1024 * 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 = (); type Err = ();
fn from_str(input: &str) -> Result<Self, <Self as std::str::FromStr>::Err> { fn from_str(input: &str) -> Result<Self, <Self as std::str::FromStr>::Err> {
match input { match input {
"B" | "b" => Ok(Unit::B), "B" | "b" => Ok(Unit::Byte),
"KB" | "kb" | "Kb" | "K" | "k" => Ok(Unit::KB), "KB" | "kb" | "Kb" | "K" | "k" => Ok(Unit::Kilobyte),
"MB" | "mb" | "Mb" => Ok(Unit::MB), "MB" | "mb" | "Mb" => Ok(Unit::Megabyte),
"GB" | "gb" | "Gb" => Ok(Unit::GB), "GB" | "gb" | "Gb" => Ok(Unit::Gigabyte),
"TB" | "tb" | "Tb" => Ok(Unit::TB), "TB" | "tb" | "Tb" => Ok(Unit::Terabyte),
"PB" | "pb" | "Pb" => Ok(Unit::PB), "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(()), _ => Err(()),
} }
} }