Improve string::is::datetime and string::is::uuid, Add string::is::record (#4462)

This commit is contained in:
Micha de Vries 2024-08-05 16:46:08 +02:00 committed by GitHub
parent 27e17d7cdd
commit 6d2f4a9833
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 54 additions and 10 deletions

View file

@ -300,6 +300,7 @@ pub fn synchronous(
"string::is::semver" => string::is::semver, "string::is::semver" => string::is::semver,
"string::is::url" => string::is::url, "string::is::url" => string::is::url,
"string::is::uuid" => string::is::uuid, "string::is::uuid" => string::is::uuid,
"string::is::record" => string::is::record,
"string::similarity::fuzzy" => string::similarity::fuzzy, "string::similarity::fuzzy" => string::similarity::fuzzy,
"string::similarity::jaro" => string::similarity::jaro, "string::similarity::jaro" => string::similarity::jaro,
"string::similarity::smithwaterman" => string::similarity::smithwaterman, "string::similarity::smithwaterman" => string::similarity::smithwaterman,

View file

@ -23,5 +23,6 @@ impl_module_def!(
"numeric" => run, "numeric" => run,
"semver" => run, "semver" => run,
"url" => run, "url" => run,
"uuid" => run "uuid" => run,
"record" => run
); );

View file

@ -183,6 +183,7 @@ pub mod html {
pub mod is { pub mod is {
use crate::err::Error; use crate::err::Error;
use crate::sql::value::Value; use crate::sql::value::Value;
use crate::sql::{Datetime, Thing};
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use regex::Regex; use regex::Regex;
@ -207,8 +208,11 @@ pub mod is {
Ok(arg.is_ascii().into()) Ok(arg.is_ascii().into())
} }
pub fn datetime((arg, fmt): (String, String)) -> Result<Value, Error> { pub fn datetime((arg, fmt): (String, Option<String>)) -> Result<Value, Error> {
Ok(NaiveDateTime::parse_from_str(&arg, &fmt).is_ok().into()) Ok(match fmt {
Some(fmt) => NaiveDateTime::parse_from_str(&arg, &fmt).is_ok().into(),
None => Datetime::try_from(arg.as_ref()).is_ok().into(),
})
} }
pub fn domain((arg,): (String,)) -> Result<Value, Error> { pub fn domain((arg,): (String,)) -> Result<Value, Error> {
@ -255,13 +259,29 @@ pub mod is {
Ok(Url::parse(&arg).is_ok().into()) Ok(Url::parse(&arg).is_ok().into())
} }
pub fn uuid((arg,): (Value,)) -> Result<Value, Error> { pub fn uuid((arg,): (String,)) -> Result<Value, Error> {
Ok(match arg { Ok(Uuid::parse_str(arg.as_ref()).is_ok().into())
Value::Strand(v) => Uuid::parse_str(v.as_string().as_str()).is_ok(), }
Value::Uuid(_) => true,
pub fn record((arg, tb): (String, Option<Value>)) -> Result<Value, Error> {
let res = match Thing::try_from(arg) {
Ok(t) => match tb {
Some(Value::Strand(tb)) => t.tb == *tb,
Some(Value::Table(tb)) => t.tb == tb.0,
Some(_) => {
return Err(Error::InvalidArguments {
name: "string::is::record()".into(),
message:
"Expected an optional string or table type for the second argument"
.into(),
})
}
None => true,
},
_ => false, _ => false,
} };
.into())
Ok(res.into())
} }
} }

View file

@ -288,6 +288,7 @@ pub(crate) static PATHS: phf::Map<UniCase<&'static str>, PathKind> = phf_map! {
UniCase::ascii("string::is::semver") => PathKind::Function, UniCase::ascii("string::is::semver") => PathKind::Function,
UniCase::ascii("string::is::url") => PathKind::Function, UniCase::ascii("string::is::url") => PathKind::Function,
UniCase::ascii("string::is::uuid") => PathKind::Function, UniCase::ascii("string::is::uuid") => PathKind::Function,
UniCase::ascii("string::is::record") => PathKind::Function,
UniCase::ascii("string::semver::compare") => PathKind::Function, UniCase::ascii("string::semver::compare") => PathKind::Function,
UniCase::ascii("string::semver::major") => PathKind::Function, UniCase::ascii("string::semver::major") => PathKind::Function,
UniCase::ascii("string::semver::minor") => PathKind::Function, UniCase::ascii("string::semver::minor") => PathKind::Function,

View file

@ -312,6 +312,7 @@
"string::is::semver(" "string::is::semver("
"string::is::url(" "string::is::url("
"string::is::uuid(" "string::is::uuid("
"string::is::record("
"string::join(" "string::join("
"string::len(" "string::len("
"string::lowercase(" "string::lowercase("

View file

@ -310,6 +310,7 @@
"string::is::semver(" "string::is::semver("
"string::is::url(" "string::is::url("
"string::is::uuid(" "string::is::uuid("
"string::is::record("
"string::join(" "string::join("
"string::len(" "string::len("
"string::lowercase(" "string::lowercase("

View file

@ -3670,7 +3670,7 @@ async fn function_parse_is_url() -> Result<(), Error> {
#[tokio::test] #[tokio::test]
async fn function_parse_is_uuid() -> Result<(), Error> { async fn function_parse_is_uuid() -> Result<(), Error> {
let sql = r#" let sql = r#"
RETURN string::is::uuid(u"e72bee20-f49b-11ec-b939-0242ac120002"); RETURN string::is::uuid("e72bee20-f49b-11ec-b939-0242ac120002");
RETURN string::is::uuid("this is a test!"); RETURN string::is::uuid("this is a test!");
"#; "#;
let mut test = Test::new(sql).await?; let mut test = Test::new(sql).await?;
@ -3686,6 +3686,25 @@ async fn function_parse_is_uuid() -> Result<(), Error> {
Ok(()) Ok(())
} }
#[tokio::test]
async fn function_parse_is_record() -> Result<(), Error> {
let sql = r#"
RETURN string::is::record("test:123");
RETURN string::is::record("invalid record id!");
"#;
let mut test = Test::new(sql).await?;
//
let tmp = test.next()?.result?;
let val = Value::Bool(true);
assert_eq!(tmp, val);
//
let tmp = test.next()?.result?;
let val = Value::Bool(false);
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test] #[tokio::test]
async fn function_string_join() -> Result<(), Error> { async fn function_string_join() -> Result<(), Error> {
let sql = r#" let sql = r#"