Make duration its own primitive

This commit is contained in:
Jonathan Turner 2019-11-17 18:48:48 +13:00
parent a7d7098b1a
commit 6231367bc8
7 changed files with 40 additions and 28 deletions

View File

@ -41,6 +41,7 @@ pub fn value_to_bson_value(v: &Tagged<Value>) -> Result<Bson, ShellError> {
.to_f64()
.expect("Unimplemented BUG: What about big decimals?"),
),
Value::Primitive(Primitive::Duration(secs)) => Bson::I64(*secs as i64),
Value::Primitive(Primitive::Date(d)) => Bson::UtcDatetime(*d),
Value::Primitive(Primitive::EndOfStream) => Bson::Null,
Value::Primitive(Primitive::BeginningOfStream) => Bson::Null,

View File

@ -32,6 +32,9 @@ pub fn value_to_json_value(v: &Tagged<Value>) -> Result<serde_json::Value, Shell
Value::Primitive(Primitive::Bytes(b)) => serde_json::Value::Number(
serde_json::Number::from(b.to_u64().expect("What about really big numbers")),
),
Value::Primitive(Primitive::Duration(secs)) => {
serde_json::Value::Number(serde_json::Number::from(*secs))
}
Value::Primitive(Primitive::Date(d)) => serde_json::Value::String(d.to_string()),
Value::Primitive(Primitive::EndOfStream) => serde_json::Value::Null,
Value::Primitive(Primitive::BeginningOfStream) => serde_json::Value::Null,

View File

@ -88,6 +88,7 @@ fn nu_value_to_sqlite_string(v: Value) -> String {
Value::Primitive(p) => match p {
Primitive::Nothing => "NULL".into(),
Primitive::Int(i) => format!("{}", i),
Primitive::Duration(u) => format!("{}", u),
Primitive::Decimal(f) => format!("{}", f),
Primitive::Bytes(u) => format!("{}", u),
Primitive::Pattern(s) => format!("'{}'", s.replace("'", "''")),

View File

@ -30,6 +30,7 @@ pub fn value_to_toml_value(v: &Tagged<Value>) -> Result<toml::Value, ShellError>
Ok(match v.item() {
Value::Primitive(Primitive::Boolean(b)) => toml::Value::Boolean(*b),
Value::Primitive(Primitive::Bytes(b)) => toml::Value::Integer(*b as i64),
Value::Primitive(Primitive::Duration(d)) => toml::Value::Integer(*d as i64),
Value::Primitive(Primitive::Date(d)) => toml::Value::String(d.to_string()),
Value::Primitive(Primitive::EndOfStream) => {
toml::Value::String("<End of Stream>".to_string())

View File

@ -32,6 +32,9 @@ pub fn value_to_yaml_value(v: &Tagged<Value>) -> Result<serde_yaml::Value, Shell
Value::Primitive(Primitive::Bytes(b)) => {
serde_yaml::Value::Number(serde_yaml::Number::from(b.to_f64().unwrap()))
}
Value::Primitive(Primitive::Duration(secs)) => {
serde_yaml::Value::Number(serde_yaml::Number::from(secs.to_f64().unwrap()))
}
Value::Primitive(Primitive::Date(d)) => serde_yaml::Value::String(d.to_string()),
Value::Primitive(Primitive::EndOfStream) => serde_yaml::Value::Null,
Value::Primitive(Primitive::BeginningOfStream) => serde_yaml::Value::Null,

View File

@ -79,6 +79,7 @@ pub enum Primitive {
Pattern(String),
Boolean(bool),
Date(DateTime<Utc>),
Duration(u64), // Duration in seconds
Path(PathBuf),
#[serde(with = "serde_bytes")]
Binary(Vec<u8>),
@ -111,6 +112,7 @@ impl Primitive {
Path(_) => "path",
Int(_) => "int",
Decimal(_) => "decimal",
Duration(_) => "duration",
Bytes(_) => "bytes",
Pattern(_) => "pattern",
String(_) => "string",
@ -131,6 +133,7 @@ impl Primitive {
Int(int) => write!(f, "{}", int),
Path(path) => write!(f, "{}", path.display()),
Decimal(decimal) => write!(f, "{}", decimal),
Duration(secs) => write!(f, "{}", secs),
Bytes(bytes) => write!(f, "{}", bytes),
Pattern(string) => write!(f, "{:?}", string),
String(string) => write!(f, "{:?}", string),
@ -169,6 +172,13 @@ impl Primitive {
_ => format!("{}", byte.format(1)),
}
}
Primitive::Duration(sec) => {
if *sec == 1 {
format!("{} sec", sec)
} else {
format!("{} secs", sec)
}
} //FIXME: make nicer duration output
Primitive::Int(i) => format!("{}", i),
Primitive::Decimal(decimal) => format!("{}", decimal),
Primitive::Pattern(s) => format!("{}", s),
@ -785,6 +795,10 @@ impl Value {
Value::Primitive(Primitive::Boolean(s.into()))
}
pub fn duration(secs: u64) -> Value {
Value::Primitive(Primitive::Duration(secs))
}
pub fn system_date(s: SystemTime) -> Value {
Value::Primitive(Primitive::Date(s.into()))
}
@ -857,6 +871,7 @@ enum CompareValues {
Decimals(BigDecimal, BigDecimal),
String(String, String),
Date(DateTime<Utc>, DateTime<Utc>),
DateDuration(DateTime<Utc>, u64),
}
impl CompareValues {
@ -865,7 +880,14 @@ 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),
CompareValues::Date(left, right) => left.cmp(right),
CompareValues::DateDuration(left, right) => {
use std::time::Duration;
// Create the datetime we're comparing against, as duration is an offset from now
let right: DateTime<Utc> = (SystemTime::now() - Duration::from_secs(*right)).into();
right.cmp(left)
}
}
}
}
@ -903,6 +925,7 @@ fn coerce_compare_primitive(
}
(String(left), String(right)) => CompareValues::String(left.clone(), right.clone()),
(Date(left), Date(right)) => CompareValues::Date(left.clone(), right.clone()),
(Date(left), Duration(right)) => CompareValues::DateDuration(left.clone(), right.clone()),
_ => return Err((left.type_name(), right.type_name())),
})
}

View File

@ -3,8 +3,6 @@ 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 {
@ -68,31 +66,13 @@ impl Unit {
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)),
),
Unit::Second => Value::duration(convert_number_to_u64(&size)),
Unit::Minute => Value::duration(60 * convert_number_to_u64(&size)),
Unit::Hour => Value::duration(60 * 60 * convert_number_to_u64(&size)),
Unit::Day => Value::duration(24 * 60 * 60 * convert_number_to_u64(&size)),
Unit::Week => Value::duration(7 * 24 * 60 * 60 * convert_number_to_u64(&size)),
Unit::Month => Value::duration(30 * 24 * 60 * 60 * convert_number_to_u64(&size)),
Unit::Year => Value::duration(365 * 24 * 60 * 60 * convert_number_to_u64(&size)),
}
}
}