Feature #1973 - Add time::ceil function. (#1975)

This commit is contained in:
Finn Bear 2023-05-11 11:46:36 -07:00 committed by GitHub
parent e90e4b57bc
commit 01b280623c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 1 deletions

View file

@ -225,6 +225,7 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
"string::uppercase" => string::uppercase,
"string::words" => string::words,
//
"time::ceil" => time::ceil,
"time::day" => time::day,
"time::floor" => time::floor,
"time::format" => time::format,

View file

@ -8,6 +8,7 @@ pub struct Package;
impl_module_def!(
Package,
"time",
"ceil" => run,
"day" => run,
"floor" => run,
"format" => run,

View file

@ -9,6 +9,22 @@ use chrono::Local;
use chrono::Timelike;
use chrono::Utc;
pub fn ceil((val, duration): (Datetime, Duration)) -> Result<Value, Error> {
match chrono::Duration::from_std(*duration) {
Ok(d) => match val.duration_trunc(d).ok().and_then(|floor| floor.checked_add_signed(d)) {
Some(v) => Ok(v.into()),
_ => Err(Error::InvalidArguments {
name: String::from("time::ceil"),
message: String::from("The second argument must be a duration, and must be able to be represented as nanoseconds."),
}),
},
_ => Err(Error::InvalidArguments {
name: String::from("time::ceil"),
message: String::from("The second argument must be a duration, and must be able to be represented as nanoseconds."),
}),
}
}
pub fn day((val,): (Option<Datetime>,)) -> Result<Value, Error> {
Ok(match val {
Some(v) => v.day().into(),
@ -18,7 +34,7 @@ pub fn day((val,): (Option<Datetime>,)) -> Result<Value, Error> {
pub fn floor((val, duration): (Datetime, Duration)) -> Result<Value, Error> {
match chrono::Duration::from_std(*duration) {
Ok(d) => match val.duration_trunc(d) {
Ok(d) => match val.duration_trunc(d){
Ok(v) => Ok(v.into()),
_ => Err(Error::InvalidArguments {
name: String::from("time::floor"),

View file

@ -514,6 +514,7 @@ fn function_string(i: &str) -> IResult<&str, &str> {
fn function_time(i: &str) -> IResult<&str, &str> {
alt((
tag("ceil"),
tag("day"),
tag("floor"),
tag("format"),

View file

@ -3554,6 +3554,28 @@ async fn function_string_words() -> Result<(), Error> {
// time
// --------------------------------------------------
#[tokio::test]
async fn function_time_ceil() -> Result<(), Error> {
let sql = r#"
RETURN time::ceil("1987-06-22T08:30:45Z", 1w);
RETURN time::ceil("1987-06-22T08:30:45Z", 1y);
"#;
let dbs = Datastore::new("memory").await?;
let ses = Session::for_kv().with_ns("test").with_db("test");
let res = &mut dbs.execute(&sql, &ses, None, false).await?;
assert_eq!(res.len(), 2);
//
let tmp = res.remove(0).result?;
let val = Value::parse("'1987-06-25T00:00:00Z'");
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::parse("'1987-12-28T00:00:00Z'");
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_time_day() -> Result<(), Error> {
let sql = r#"