move is::* -> string::is::*, add new type::is::* fncs (#2603)

This commit is contained in:
Micha de Vries 2023-09-04 18:10:18 +02:00 committed by GitHub
parent 7265136c0a
commit 22c36b80c8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 1295 additions and 554 deletions

View file

@ -253,7 +253,7 @@ DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD name ON TABLE user TYPE object;
DEFINE FIELD name.first ON TABLE user TYPE string;
DEFINE FIELD name.last ON TABLE user TYPE string;
DEFINE FIELD email ON TABLE user TYPE string ASSERT is::email($value);
DEFINE FIELD email ON TABLE user TYPE string ASSERT string::is::email($value);
-- Add a unique index on the email field preventing duplicate values
DEFINE INDEX email ON TABLE user COLUMNS email UNIQUE;

View file

@ -187,7 +187,7 @@ DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD name ON TABLE user TYPE object;
DEFINE FIELD name.first ON TABLE user TYPE string;
DEFINE FIELD name.last ON TABLE user TYPE string;
DEFINE FIELD email ON TABLE user TYPE string ASSERT is::email($value);
DEFINE FIELD email ON TABLE user TYPE string ASSERT string::is::email($value);
-- Add a unique index on the email field preventing duplicate values
DEFINE INDEX email ON TABLE user COLUMNS email UNIQUE;

View file

@ -222,21 +222,6 @@
"http::post("
"http::patch("
"http::delete("
"is"
"is::"
"is::alphanum("
"is::alpha("
"is::ascii("
"is::datetime("
"is::domain("
"is::email("
"is::hexadecimal("
"is::latitude("
"is::longitude("
"is::numeric("
"is::semver("
"is::url("
"is::uuid("
"math"
"math::"
"math::abs("
@ -299,6 +284,19 @@
"string::distance::hamming("
"string::distance::levenshtein("
"string::endsWith("
"string::is::alphanum("
"string::is::alpha("
"string::is::ascii("
"string::is::datetime("
"string::is::domain("
"string::is::email("
"string::is::hexadecimal("
"string::is::latitude("
"string::is::longitude("
"string::is::numeric("
"string::is::semver("
"string::is::url("
"string::is::uuid("
"string::join("
"string::len("
"string::lowercase("
@ -344,6 +342,28 @@
"type::duration("
"type::float("
"type::int("
"type::is::array("
"type::is::bool("
"type::is::bytes("
"type::is::collection("
"type::is::datetime("
"type::is::decimal("
"type::is::duration("
"type::is::float("
"type::is::geometry("
"type::is::int("
"type::is::line("
"type::is::null("
"type::is::multiline("
"type::is::multipoint("
"type::is::multipolygon("
"type::is::number("
"type::is::object("
"type::is::point("
"type::is::polygon("
"type::is::record("
"type::is::string("
"type::is::uuid("
"type::number("
"type::point("
"type::string("

View file

@ -222,21 +222,6 @@
"http::post("
"http::patch("
"http::delete("
"is"
"is::"
"is::alphanum("
"is::alpha("
"is::ascii("
"is::datetime("
"is::domain("
"is::email("
"is::hexadecimal("
"is::latitude("
"is::longitude("
"is::numeric("
"is::semver("
"is::url("
"is::uuid("
"math"
"math::"
"math::abs("
@ -298,6 +283,19 @@
"string::distance::hamming("
"string::distance::levenshtein("
"string::endsWith("
"string::is::alphanum("
"string::is::alpha("
"string::is::ascii("
"string::is::datetime("
"string::is::domain("
"string::is::email("
"string::is::hexadecimal("
"string::is::latitude("
"string::is::longitude("
"string::is::numeric("
"string::is::semver("
"string::is::url("
"string::is::uuid("
"string::join("
"string::len("
"string::lowercase("
@ -342,6 +340,28 @@
"type::decimal("
"type::duration("
"type::float("
"type::is::array("
"type::is::bool("
"type::is::bytes("
"type::is::collection("
"type::is::datetime("
"type::is::decimal("
"type::is::duration("
"type::is::float("
"type::is::geometry("
"type::is::int("
"type::is::line("
"type::is::null("
"type::is::multiline("
"type::is::multipoint("
"type::is::multipolygon("
"type::is::number("
"type::is::object("
"type::is::point("
"type::is::polygon("
"type::is::record("
"type::is::string("
"type::is::uuid("
"type::int("
"type::number("
"type::point("

View file

@ -1,190 +0,0 @@
use crate::err::Error;
use crate::sql::value::Value;
use chrono::NaiveDateTime;
use once_cell::sync::Lazy;
use regex::Regex;
use semver::Version;
use std::char;
use url::Url;
use uuid::Uuid;
#[rustfmt::skip] static LATITUDE_RE: Lazy<Regex> = Lazy::new(|| Regex::new("^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$").unwrap());
#[rustfmt::skip] static LONGITUDE_RE: Lazy<Regex> = Lazy::new(|| Regex::new("^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$").unwrap());
#[inline]
pub fn alphanum((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(char::is_alphanumeric).into())
}
#[inline]
pub fn alpha((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(char::is_alphabetic).into())
}
#[inline]
pub fn ascii((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.is_ascii().into())
}
#[inline]
pub fn datetime((arg, fmt): (String, String)) -> Result<Value, Error> {
Ok(NaiveDateTime::parse_from_str(&arg, &fmt).is_ok().into())
}
#[inline]
pub fn domain((arg,): (String,)) -> Result<Value, Error> {
Ok(addr::parse_domain_name(arg.as_str()).is_ok().into())
}
#[inline]
pub fn email((arg,): (String,)) -> Result<Value, Error> {
Ok(addr::parse_email_address(arg.as_str()).is_ok().into())
}
#[inline]
pub fn hexadecimal((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(|x| char::is_ascii_hexdigit(&x)).into())
}
#[inline]
pub fn latitude((arg,): (String,)) -> Result<Value, Error> {
Ok(LATITUDE_RE.is_match(arg.as_str()).into())
}
#[inline]
pub fn longitude((arg,): (String,)) -> Result<Value, Error> {
Ok(LONGITUDE_RE.is_match(arg.as_str()).into())
}
#[inline]
pub fn numeric((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(char::is_numeric).into())
}
#[inline]
pub fn semver((arg,): (String,)) -> Result<Value, Error> {
Ok(Version::parse(arg.as_str()).is_ok().into())
}
#[inline]
pub fn url((arg,): (String,)) -> Result<Value, Error> {
Ok(Url::parse(&arg).is_ok().into())
}
#[inline]
pub fn uuid((arg,): (Value,)) -> Result<Value, Error> {
Ok(match arg {
Value::Strand(v) => Uuid::parse_str(v.as_string().as_str()).is_ok(),
Value::Uuid(_) => true,
_ => false,
}
.into())
}
#[cfg(test)]
mod tests {
use crate::sql::value::Value;
#[test]
fn alphanum() {
let value = super::alphanum((String::from("abc123"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::alphanum((String::from("y%*"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn alpha() {
let value = super::alpha((String::from("abc"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::alpha((String::from("1234"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn ascii() {
let value = super::ascii((String::from("abc"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::ascii((String::from("中国"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn domain() {
let value = super::domain((String::from("食狮.中国"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::domain((String::from("example-.com"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn email() {
let input = (String::from("user@[fd79:cdcb:38cc:9dd:f686:e06d:32f3:c123]"),);
let value = super::email(input).unwrap();
assert_eq!(value, Value::Bool(true));
let input = (String::from("john..doe@example.com"),);
let value = super::email(input).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn hexadecimal() {
let value = super::hexadecimal((String::from("00FF00"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::hexadecimal((String::from("SurrealDB"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn latitude() {
let value = super::latitude((String::from("-0.118092"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::latitude((String::from("12345"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn longitude() {
let value = super::longitude((String::from("51.509865"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::longitude((String::from("12345"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn numeric() {
let value = super::numeric((String::from("12345"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::numeric((String::from("abcde"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn semver() {
let value = super::semver((String::from("1.0.0"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::semver((String::from("1.0"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn uuid() {
let input = (String::from("123e4567-e89b-12d3-a456-426614174000").into(),);
let value = super::uuid(input).unwrap();
assert_eq!(value, Value::Bool(true));
let input = (String::from("foo-bar").into(),);
let value = super::uuid(input).unwrap();
assert_eq!(value, Value::Bool(false));
}
}

View file

@ -15,7 +15,6 @@ pub mod duration;
pub mod encoding;
pub mod geo;
pub mod http;
pub mod is;
pub mod math;
pub mod meta;
pub mod not;
@ -162,20 +161,6 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
"geo::hash::decode" => geo::hash::decode,
"geo::hash::encode" => geo::hash::encode,
//
"is::alphanum" => is::alphanum,
"is::alpha" => is::alpha,
"is::ascii" => is::ascii,
"is::datetime" => is::datetime,
"is::domain" => is::domain,
"is::email" => is::email,
"is::hexadecimal" => is::hexadecimal,
"is::latitude" => is::latitude,
"is::longitude" => is::longitude,
"is::numeric" => is::numeric,
"is::semver" => is::semver,
"is::url" => is::url,
"is::uuid" => is::uuid,
//
"math::abs" => math::abs,
"math::bottom" => math::bottom,
"math::ceil" => math::ceil,
@ -257,6 +242,19 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
"string::words" => string::words,
"string::distance::hamming" => string::distance::hamming,
"string::distance::levenshtein" => string::distance::levenshtein,
"string::is::alphanum" => string::is::alphanum,
"string::is::alpha" => string::is::alpha,
"string::is::ascii" => string::is::ascii,
"string::is::datetime" => string::is::datetime,
"string::is::domain" => string::is::domain,
"string::is::email" => string::is::email,
"string::is::hexadecimal" => string::is::hexadecimal,
"string::is::latitude" => string::is::latitude,
"string::is::longitude" => string::is::longitude,
"string::is::numeric" => string::is::numeric,
"string::is::semver" => string::is::semver,
"string::is::url" => string::is::url,
"string::is::uuid" => string::is::uuid,
"string::similarity::fuzzy" => string::similarity::fuzzy,
"string::similarity::jaro" => string::similarity::jaro,
"string::similarity::smithwaterman" => string::similarity::smithwaterman,
@ -297,6 +295,28 @@ pub fn synchronous(ctx: &Context<'_>, name: &str, args: Vec<Value>) -> Result<Va
"type::string" => r#type::string,
"type::table" => r#type::table,
"type::thing" => r#type::thing,
"type::is::array" => r#type::is::array,
"type::is::bool" => r#type::is::bool,
"type::is::bytes" => r#type::is::bytes,
"type::is::collection" => r#type::is::collection,
"type::is::datetime" => r#type::is::datetime,
"type::is::decimal" => r#type::is::decimal,
"type::is::duration" => r#type::is::duration,
"type::is::float" => r#type::is::float,
"type::is::geometry" => r#type::is::geometry,
"type::is::int" => r#type::is::int,
"type::is::line" => r#type::is::line,
"type::is::null" => r#type::is::null,
"type::is::multiline" => r#type::is::multiline,
"type::is::multipoint" => r#type::is::multipoint,
"type::is::multipolygon" => r#type::is::multipolygon,
"type::is::number" => r#type::is::number,
"type::is::object" => r#type::is::object,
"type::is::point" => r#type::is::point,
"type::is::polygon" => r#type::is::polygon,
"type::is::record" => r#type::is::record,
"type::is::string" => r#type::is::string,
"type::is::uuid" => r#type::is::uuid,
//
"vector::add" => vector::add,
"vector::angle" => vector::angle,

View file

@ -14,7 +14,6 @@ mod duration;
mod encoding;
mod geo;
mod http;
mod is;
mod math;
mod meta;
mod parse;
@ -39,7 +38,6 @@ impl_module_def!(
"encoding" => (encoding::Package),
"geo" => (geo::Package),
"http" => (http::Package),
"is" => (is::Package),
"math" => (math::Package),
"meta" => (meta::Package),
"not" => run,

View file

@ -2,6 +2,7 @@ use super::run;
use crate::fnc::script::modules::impl_module_def;
mod distance;
mod is;
mod similarity;
pub struct Package;
@ -12,6 +13,7 @@ impl_module_def!(
"contains" => run,
"distance" => (distance::Package),
"endsWith" => run,
"is" => (is::Package),
"join" => run,
"len" => run,
"lowercase" => run,

View file

@ -5,7 +5,7 @@ pub struct Package;
impl_module_def!(
Package,
"is",
"string::is",
"alphanum" => run,
"alpha" => run,
"ascii" => run,

View file

@ -3,6 +3,8 @@ use super::run;
use crate::fnc::script::modules::impl_module_def;
use js::prelude::Async;
mod is;
pub struct Package;
impl_module_def!(
@ -16,6 +18,7 @@ impl_module_def!(
"fields" => fut Async,
"float" => run,
"int" => run,
"is" => (is::Package),
"number" => run,
"point" => run,
"regex" => run,

View file

@ -0,0 +1,31 @@
use super::run;
use crate::fnc::script::modules::impl_module_def;
pub struct Package;
impl_module_def!(
Package,
"type::is",
"array" => run,
"bool" => run,
"bytes" => run,
"collection" => run,
"datetime" => run,
"decimal" => run,
"duration" => run,
"float" => run,
"geometry" => run,
"int" => run,
"line" => run,
"null" => run,
"multiline" => run,
"multipoint" => run,
"multipolygon" => run,
"number" => run,
"object" => run,
"point" => run,
"polygon" => run,
"record" => run,
"string" => run,
"uuid" => run
);

View file

@ -151,6 +151,77 @@ pub mod distance {
}
}
pub mod is {
use crate::err::Error;
use crate::sql::value::Value;
use chrono::NaiveDateTime;
use once_cell::sync::Lazy;
use regex::Regex;
use semver::Version;
use std::char;
use url::Url;
use uuid::Uuid;
#[rustfmt::skip] static LATITUDE_RE: Lazy<Regex> = Lazy::new(|| Regex::new("^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$").unwrap());
#[rustfmt::skip] static LONGITUDE_RE: Lazy<Regex> = Lazy::new(|| Regex::new("^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$").unwrap());
pub fn alphanum((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(char::is_alphanumeric).into())
}
pub fn alpha((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(char::is_alphabetic).into())
}
pub fn ascii((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.is_ascii().into())
}
pub fn datetime((arg, fmt): (String, String)) -> Result<Value, Error> {
Ok(NaiveDateTime::parse_from_str(&arg, &fmt).is_ok().into())
}
pub fn domain((arg,): (String,)) -> Result<Value, Error> {
Ok(addr::parse_domain_name(arg.as_str()).is_ok().into())
}
pub fn email((arg,): (String,)) -> Result<Value, Error> {
Ok(addr::parse_email_address(arg.as_str()).is_ok().into())
}
pub fn hexadecimal((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(|x| char::is_ascii_hexdigit(&x)).into())
}
pub fn latitude((arg,): (String,)) -> Result<Value, Error> {
Ok(LATITUDE_RE.is_match(arg.as_str()).into())
}
pub fn longitude((arg,): (String,)) -> Result<Value, Error> {
Ok(LONGITUDE_RE.is_match(arg.as_str()).into())
}
pub fn numeric((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.chars().all(char::is_numeric).into())
}
pub fn semver((arg,): (String,)) -> Result<Value, Error> {
Ok(Version::parse(arg.as_str()).is_ok().into())
}
pub fn url((arg,): (String,)) -> Result<Value, Error> {
Ok(Url::parse(&arg).is_ok().into())
}
pub fn uuid((arg,): (Value,)) -> Result<Value, Error> {
Ok(match arg {
Value::Strand(v) => Uuid::parse_str(v.as_string().as_str()).is_ok(),
Value::Uuid(_) => true,
_ => false,
}
.into())
}
}
pub mod similarity {
use crate::err::Error;
@ -216,4 +287,107 @@ mod tests {
test("好世界", "", true);
test("好世界", "你好", false);
}
#[test]
fn is_alphanum() {
let value = super::is::alphanum((String::from("abc123"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::alphanum((String::from("y%*"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_alpha() {
let value = super::is::alpha((String::from("abc"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::alpha((String::from("1234"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_ascii() {
let value = super::is::ascii((String::from("abc"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::ascii((String::from("中国"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_domain() {
let value = super::is::domain((String::from("食狮.中国"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::domain((String::from("example-.com"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_email() {
let input = (String::from("user@[fd79:cdcb:38cc:9dd:f686:e06d:32f3:c123]"),);
let value = super::is::email(input).unwrap();
assert_eq!(value, Value::Bool(true));
let input = (String::from("john..doe@example.com"),);
let value = super::is::email(input).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_hexadecimal() {
let value = super::is::hexadecimal((String::from("00FF00"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::hexadecimal((String::from("SurrealDB"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_latitude() {
let value = super::is::latitude((String::from("-0.118092"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::latitude((String::from("12345"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_longitude() {
let value = super::is::longitude((String::from("51.509865"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::longitude((String::from("12345"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_numeric() {
let value = super::is::numeric((String::from("12345"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::numeric((String::from("abcde"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_semver() {
let value = super::is::semver((String::from("1.0.0"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::semver((String::from("1.0"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_uuid() {
let input = (String::from("123e4567-e89b-12d3-a456-426614174000").into(),);
let value = super::is::uuid(input).unwrap();
assert_eq!(value, Value::Bool(true));
let input = (String::from("foo-bar").into(),);
let value = super::is::uuid(input).unwrap();
assert_eq!(value, Value::Bool(false));
}
}

View file

@ -119,3 +119,111 @@ pub fn thing((arg1, arg2): (Value, Option<Value>)) -> Result<Value, Error> {
}
})
}
pub mod is {
use crate::err::Error;
use crate::sql::value::Value;
use crate::sql::Geometry;
pub fn array((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_array().into())
}
pub fn bool((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_bool().into())
}
pub fn bytes((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_bytes().into())
}
pub fn collection((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::Collection(_))).into())
}
pub fn datetime((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_datetime().into())
}
pub fn decimal((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_decimal().into())
}
pub fn duration((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_duration().into())
}
pub fn float((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_float().into())
}
pub fn geometry((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_geometry().into())
}
pub fn int((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_int().into())
}
pub fn line((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::Line(_))).into())
}
pub fn null((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_null().into())
}
pub fn multiline((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::MultiLine(_))).into())
}
pub fn multipoint((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::MultiPoint(_))).into())
}
pub fn multipolygon((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::MultiPolygon(_))).into())
}
pub fn number((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_number().into())
}
pub fn object((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_object().into())
}
pub fn point((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::Point(_))).into())
}
pub fn polygon((arg,): (Value,)) -> Result<Value, Error> {
Ok(matches!(arg, Value::Geometry(Geometry::Polygon(_))).into())
}
pub fn record((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_record().into())
}
pub fn string((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_strand().into())
}
pub fn uuid((arg,): (Value,)) -> Result<Value, Error> {
Ok(arg.is_uuid().into())
}
}
#[cfg(test)]
mod tests {
use crate::sql::value::Value;
#[test]
fn is_array() {
let value = super::is::array((vec!["hello", "world"].into(),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::array(("test".into(),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
}

View file

@ -311,7 +311,6 @@ pub(crate) fn function_names(i: &str) -> IResult<&str, &str> {
preceded(tag("encoding::"), cut(function_encoding)),
preceded(tag("geo::"), cut(function_geo)),
preceded(tag("http::"), cut(function_http)),
preceded(tag("is::"), cut(function_is)),
// Don't cut in time and math for now since there are also constant's with the same
// prefix.
preceded(tag("math::"), function_math),
@ -446,24 +445,6 @@ fn function_http(i: &str) -> IResult<&str, &str> {
alt((tag("head"), tag("get"), tag("put"), tag("post"), tag("patch"), tag("delete")))(i)
}
fn function_is(i: &str) -> IResult<&str, &str> {
alt((
tag("alphanum"),
tag("alpha"),
tag("ascii"),
tag("datetime"),
tag("domain"),
tag("email"),
tag("hexadecimal"),
tag("latitude"),
tag("longitude"),
tag("numeric"),
tag("semver"),
tag("url"),
tag("uuid"),
))(i)
}
fn function_math(i: &str) -> IResult<&str, &str> {
alt((
alt((
@ -571,6 +552,24 @@ fn function_string(i: &str) -> IResult<&str, &str> {
tag("uppercase"),
tag("words"),
preceded(tag("distance::"), alt((tag("hamming"), tag("levenshtein")))),
preceded(
tag("is::"),
alt((
tag("alphanum"),
tag("alpha"),
tag("ascii"),
tag("datetime"),
tag("domain"),
tag("email"),
tag("hexadecimal"),
tag("latitude"),
tag("longitude"),
tag("numeric"),
tag("semver"),
tag("url"),
tag("uuid"),
)),
),
preceded(tag("similarity::"), alt((tag("fuzzy"), tag("jaro"), tag("smithwaterman")))),
))(i)
}
@ -616,6 +615,37 @@ fn function_type(i: &str) -> IResult<&str, &str> {
tag("string"),
tag("table"),
tag("thing"),
preceded(
tag("is::"),
alt((
alt((
tag("array"),
tag("bool"),
tag("bytes"),
tag("collection"),
tag("datetime"),
tag("decimal"),
tag("duration"),
tag("float"),
tag("geometry"),
tag("int"),
tag("line"),
)),
alt((
tag("null"),
tag("multiline"),
tag("multipoint"),
tag("multipolygon"),
tag("number"),
tag("object"),
tag("point"),
tag("polygon"),
tag("record"),
tag("string"),
tag("uuid"),
)),
)),
),
))(i)
}
@ -684,11 +714,11 @@ mod tests {
#[test]
fn function_arguments() {
let sql = "is::numeric(null)";
let sql = "string::is::numeric(null)";
let res = function(sql);
let out = res.unwrap().1;
assert_eq!("is::numeric(NULL)", format!("{}", out));
assert_eq!(out, Function::Normal(String::from("is::numeric"), vec![Value::Null]));
assert_eq!("string::is::numeric(NULL)", format!("{}", out));
assert_eq!(out, Function::Normal(String::from("string::is::numeric"), vec![Value::Null]));
}
#[test]

View file

@ -12,7 +12,7 @@ async fn field_definition_value_assert_failure() -> Result<(), Error> {
let sql = "
DEFINE TABLE person SCHEMAFULL;
DEFINE FIELD age ON person TYPE number ASSERT $value > 0;
DEFINE FIELD email ON person TYPE string ASSERT is::email($value);
DEFINE FIELD email ON person TYPE string ASSERT string::is::email($value);
DEFINE FIELD name ON person TYPE option<string> VALUE $value OR 'No name';
CREATE person:test SET email = 'info@surrealdb.com', other = 'ignore';
CREATE person:test SET email = 'info@surrealdb.com', other = 'ignore', age = NONE;
@ -99,7 +99,7 @@ async fn field_definition_value_assert_success() -> Result<(), Error> {
let sql = "
DEFINE TABLE person SCHEMAFULL;
DEFINE FIELD age ON person TYPE number ASSERT $value > 0;
DEFINE FIELD email ON person TYPE string ASSERT is::email($value);
DEFINE FIELD email ON person TYPE string ASSERT string::is::email($value);
DEFINE FIELD name ON person TYPE option<string> VALUE $value OR 'No name';
CREATE person:test SET email = 'info@surrealdb.com', other = 'ignore', age = 22;
";

File diff suppressed because it is too large Load diff