Add string functions for IP ()

Signed-off-by: Obei Sideg <obei.sideg@gmail.com>
This commit is contained in:
Obei Sideg 2024-05-30 16:15:08 -04:00 committed by GitHub
parent 468d2166c6
commit 876f281be5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 121 additions and 0 deletions
core/src
fnc
mod.rs
script/modules/surrealdb/functions/string
string.rs
syn/parser
lib

View file

@ -270,6 +270,9 @@ pub fn synchronous(
"string::is::domain" => string::is::domain,
"string::is::email" => string::is::email,
"string::is::hexadecimal" => string::is::hexadecimal,
"string::is::ip" => string::is::ip,
"string::is::ipv4" => string::is::ipv4,
"string::is::ipv6" => string::is::ipv6,
"string::is::latitude" => string::is::latitude,
"string::is::longitude" => string::is::longitude,
"string::is::numeric" => string::is::numeric,

View file

@ -15,6 +15,9 @@ impl_module_def!(
"email" => run,
"email" => run,
"hexadecimal" => run,
"ip" => run,
"ipv4" => run,
"ipv6" => run,
"latitude" => run,
"longitude" => run,
"numeric" => run,

View file

@ -175,6 +175,7 @@ pub mod is {
use regex::Regex;
use semver::Version;
use std::char;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use url::Url;
use uuid::Uuid;
@ -209,6 +210,18 @@ pub mod is {
Ok(arg.chars().all(|x| char::is_ascii_hexdigit(&x)).into())
}
pub fn ip((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.parse::<IpAddr>().is_ok().into())
}
pub fn ipv4((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.parse::<Ipv4Addr>().is_ok().into())
}
pub fn ipv6((arg,): (String,)) -> Result<Value, Error> {
Ok(arg.parse::<Ipv6Addr>().is_ok().into())
}
pub fn latitude((arg,): (String,)) -> Result<Value, Error> {
Ok(LATITUDE_RE.is_match(arg.as_str()).into())
}
@ -509,6 +522,33 @@ mod tests {
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_ip() {
let value = super::is::ip((String::from("127.0.0.1"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::ip((String::from("127.0.0"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_ipv4() {
let value = super::is::ipv4((String::from("127.0.0.1"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::ipv4((String::from("127.0.0"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_ipv6() {
let value = super::is::ipv6((String::from("::1"),)).unwrap();
assert_eq!(value, Value::Bool(true));
let value = super::is::ipv6((String::from("200t:db8::"),)).unwrap();
assert_eq!(value, Value::Bool(false));
}
#[test]
fn is_latitude() {
let value = super::is::latitude((String::from("-0.118092"),)).unwrap();

View file

@ -255,6 +255,9 @@ pub(crate) static PATHS: phf::Map<UniCase<&'static str>, PathKind> = phf_map! {
UniCase::ascii("string::is::domain") => PathKind::Function,
UniCase::ascii("string::is::email") => PathKind::Function,
UniCase::ascii("string::is::hexadecimal") => PathKind::Function,
UniCase::ascii("string::is::ip") => PathKind::Function,
UniCase::ascii("string::is::ipv4") => PathKind::Function,
UniCase::ascii("string::is::ipv6") => PathKind::Function,
UniCase::ascii("string::is::latitude") => PathKind::Function,
UniCase::ascii("string::is::longitude") => PathKind::Function,
UniCase::ascii("string::is::numeric") => PathKind::Function,

View file

@ -301,6 +301,9 @@
"string::is::domain("
"string::is::email("
"string::is::hexadecimal("
"string::is::ip("
"string::is::ipv4("
"string::is::ipv6("
"string::is::latitude("
"string::is::longitude("
"string::is::numeric("

View file

@ -299,6 +299,9 @@
"string::is::domain("
"string::is::email("
"string::is::hexadecimal("
"string::is::ip("
"string::is::ipv4("
"string::is::ipv6("
"string::is::latitude("
"string::is::longitude("
"string::is::numeric("

View file

@ -3705,6 +3705,72 @@ async fn function_parse_is_hexadecimal() -> Result<(), Error> {
Ok(())
}
#[tokio::test]
async fn function_parse_is_ip() -> Result<(), Error> {
let sql = r#"
RETURN string::is::ip("127.0.0.1");
RETURN string::is::ip("127.0.0");
"#;
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 2);
//
let tmp = res.remove(0).result?;
let val = Value::Bool(true);
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::Bool(false);
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_parse_is_ipv4() -> Result<(), Error> {
let sql = r#"
RETURN string::is::ipv4("127.0.0.1");
RETURN string::is::ipv4("127.0.0");
"#;
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 2);
//
let tmp = res.remove(0).result?;
let val = Value::Bool(true);
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::Bool(false);
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_parse_is_ipv6() -> Result<(), Error> {
let sql = r#"
RETURN string::is::ipv6("::1");
RETURN string::is::ipv6("200t:db8::");
"#;
let dbs = new_ds().await?;
let ses = Session::owner().with_ns("test").with_db("test");
let res = &mut dbs.execute(sql, &ses, None).await?;
assert_eq!(res.len(), 2);
//
let tmp = res.remove(0).result?;
let val = Value::Bool(true);
assert_eq!(tmp, val);
//
let tmp = res.remove(0).result?;
let val = Value::Bool(false);
assert_eq!(tmp, val);
//
Ok(())
}
#[tokio::test]
async fn function_parse_is_latitude() -> Result<(), Error> {
let sql = r#"