diff --git a/lib/src/fnc/crypto.rs b/lib/src/fnc/crypto.rs index 36ccaa83..ed40dd3f 100644 --- a/lib/src/fnc/crypto.rs +++ b/lib/src/fnc/crypto.rs @@ -9,7 +9,7 @@ use sha2::Sha512; pub fn md5(_: &Runtime, mut args: Vec) -> Result { let mut hasher = Md5::new(); - hasher.update(args.remove(0).as_strand().as_str()); + hasher.update(args.remove(0).as_string().as_str()); let val = hasher.finalize(); let val = format!("{:x}", val); Ok(val.into()) @@ -17,7 +17,7 @@ pub fn md5(_: &Runtime, mut args: Vec) -> Result { pub fn sha1(_: &Runtime, mut args: Vec) -> Result { let mut hasher = Sha1::new(); - hasher.update(args.remove(0).as_strand().as_str()); + hasher.update(args.remove(0).as_string().as_str()); let val = hasher.finalize(); let val = format!("{:x}", val); Ok(val.into()) @@ -25,7 +25,7 @@ pub fn sha1(_: &Runtime, mut args: Vec) -> Result { pub fn sha256(_: &Runtime, mut args: Vec) -> Result { let mut hasher = Sha256::new(); - hasher.update(args.remove(0).as_strand().as_str()); + hasher.update(args.remove(0).as_string().as_str()); let val = hasher.finalize(); let val = format!("{:x}", val); Ok(val.into()) @@ -33,7 +33,7 @@ pub fn sha256(_: &Runtime, mut args: Vec) -> Result { pub fn sha512(_: &Runtime, mut args: Vec) -> Result { let mut hasher = Sha512::new(); - hasher.update(args.remove(0).as_strand().as_str()); + hasher.update(args.remove(0).as_string().as_str()); let val = hasher.finalize(); let val = format!("{:x}", val); Ok(val.into()) @@ -52,15 +52,15 @@ pub mod argon2 { pub fn cmp(_: &Runtime, mut args: Vec) -> Result { let algo = Argon2::default(); - let hash = args.remove(0).as_strand().value; - let pass = args.remove(0).as_strand().value; + let hash = args.remove(0).as_string(); + let pass = args.remove(0).as_string(); let test = PasswordHash::new(&hash).unwrap(); Ok(algo.verify_password(pass.as_ref(), &test).is_ok().into()) } pub fn gen(_: &Runtime, mut args: Vec) -> Result { let algo = Argon2::default(); - let pass = args.remove(0).as_strand().value; + let pass = args.remove(0).as_string(); let salt = SaltString::generate(&mut OsRng); let hash = algo.hash_password(pass.as_ref(), salt.as_ref()).unwrap().to_string(); Ok(hash.into()) @@ -79,14 +79,14 @@ pub mod pbkdf2 { use rand::rngs::OsRng; pub fn cmp(_: &Runtime, mut args: Vec) -> Result { - let hash = args.remove(0).as_strand().value; - let pass = args.remove(0).as_strand().value; + let hash = args.remove(0).as_string(); + let pass = args.remove(0).as_string(); let test = PasswordHash::new(&hash).unwrap(); Ok(Pbkdf2.verify_password(pass.as_ref(), &test).is_ok().into()) } pub fn gen(_: &Runtime, mut args: Vec) -> Result { - let pass = args.remove(0).as_strand().value; + let pass = args.remove(0).as_string(); let salt = SaltString::generate(&mut OsRng); let hash = Pbkdf2.hash_password(pass.as_ref(), salt.as_ref()).unwrap().to_string(); Ok(hash.into()) @@ -105,14 +105,14 @@ pub mod scrypt { }; pub fn cmp(_: &Runtime, mut args: Vec) -> Result { - let hash = args.remove(0).as_strand().value; - let pass = args.remove(0).as_strand().value; + let hash = args.remove(0).as_string(); + let pass = args.remove(0).as_string(); let test = PasswordHash::new(&hash).unwrap(); Ok(Scrypt.verify_password(pass.as_ref(), &test).is_ok().into()) } pub fn gen(_: &Runtime, mut args: Vec) -> Result { - let pass = args.remove(0).as_strand().value; + let pass = args.remove(0).as_string(); let salt = SaltString::generate(&mut OsRng); let hash = Scrypt.hash_password(pass.as_ref(), salt.as_ref()).unwrap().to_string(); Ok(hash.into()) diff --git a/lib/src/fnc/is.rs b/lib/src/fnc/is.rs index 93df6e8b..9ff13ecd 100644 --- a/lib/src/fnc/is.rs +++ b/lib/src/fnc/is.rs @@ -14,24 +14,24 @@ use std::char; #[rustfmt::skip] static LONGITUDE_RE: Lazy = Lazy::new(|| Regex::new("^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$").unwrap()); pub fn alphanum(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.chars().all(char::is_alphanumeric).into()) + Ok(args.remove(0).as_string().chars().all(char::is_alphanumeric).into()) } pub fn alpha(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.chars().all(char::is_alphabetic).into()) + Ok(args.remove(0).as_string().chars().all(char::is_alphabetic).into()) } pub fn ascii(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.chars().all(|x| char::is_ascii(&x)).into()) + Ok(args.remove(0).as_string().chars().all(|x| char::is_ascii(&x)).into()) } pub fn domain(_: &Runtime, mut args: Vec) -> Result { - Ok(DOMAIN_RE.is_match(args.remove(0).as_strand().as_str()).into()) + Ok(DOMAIN_RE.is_match(args.remove(0).as_string().as_str()).into()) } pub fn email(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Convert to a &str let val = val.as_str(); // Check if value is empty @@ -57,25 +57,25 @@ pub fn email(_: &Runtime, mut args: Vec) -> Result { } pub fn hexadecimal(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.chars().all(|x| char::is_ascii_hexdigit(&x)).into()) + Ok(args.remove(0).as_string().chars().all(|x| char::is_ascii_hexdigit(&x)).into()) } pub fn latitude(_: &Runtime, mut args: Vec) -> Result { - Ok(LATITUDE_RE.is_match(args.remove(0).as_strand().as_str()).into()) + Ok(LATITUDE_RE.is_match(args.remove(0).as_string().as_str()).into()) } pub fn longitude(_: &Runtime, mut args: Vec) -> Result { - Ok(LONGITUDE_RE.is_match(args.remove(0).as_strand().as_str()).into()) + Ok(LONGITUDE_RE.is_match(args.remove(0).as_string().as_str()).into()) } pub fn numeric(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.chars().all(char::is_numeric).into()) + Ok(args.remove(0).as_string().chars().all(char::is_numeric).into()) } pub fn semver(_: &Runtime, mut args: Vec) -> Result { - Ok(SEMVER_RE.is_match(args.remove(0).as_strand().as_str()).into()) + Ok(SEMVER_RE.is_match(args.remove(0).as_string().as_str()).into()) } pub fn uuid(_: &Runtime, mut args: Vec) -> Result { - Ok(UUID_RE.is_match(args.remove(0).as_strand().as_str()).into()) + Ok(UUID_RE.is_match(args.remove(0).as_string().as_str()).into()) } diff --git a/lib/src/fnc/parse.rs b/lib/src/fnc/parse.rs index 467aeb8a..fa1bb06e 100644 --- a/lib/src/fnc/parse.rs +++ b/lib/src/fnc/parse.rs @@ -11,7 +11,7 @@ pub mod email { pub fn domain(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Check if value is empty if val.is_empty() { return Ok(Value::None); @@ -36,7 +36,7 @@ pub mod email { pub fn user(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Check if value is empty if val.is_empty() { return Ok(Value::None); @@ -69,7 +69,7 @@ pub mod url { pub fn domain(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Parse the URL match Url::parse(&val) { Ok(v) => match v.domain() { @@ -82,7 +82,7 @@ pub mod url { pub fn fragment(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Parse the URL match Url::parse(&val) { Ok(v) => match v.fragment() { @@ -95,7 +95,7 @@ pub mod url { pub fn host(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Parse the URL match Url::parse(&val) { Ok(v) => match v.host_str() { @@ -108,7 +108,7 @@ pub mod url { pub fn path(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Parse the URL match Url::parse(&val) { Ok(v) => Ok(v.path().into()), @@ -118,7 +118,7 @@ pub mod url { pub fn port(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Parse the URL match Url::parse(&val) { Ok(v) => match v.port() { @@ -131,7 +131,7 @@ pub mod url { pub fn query(_: &Runtime, mut args: Vec) -> Result { // Convert to a String - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); // Parse the URL match Url::parse(&val) { Ok(v) => match v.query() { diff --git a/lib/src/fnc/string.rs b/lib/src/fnc/string.rs index dcda954b..5e4957b8 100644 --- a/lib/src/fnc/string.rs +++ b/lib/src/fnc/string.rs @@ -4,51 +4,51 @@ use crate::sql::value::Value; use slug::slugify; pub fn concat(_: &Runtime, args: Vec) -> Result { - Ok(args.into_iter().map(|x| x.as_strand().value).collect::>().concat().into()) + Ok(args.into_iter().map(|x| x.as_string()).collect::>().concat().into()) } pub fn ends_with(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; - let chr = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); + let chr = args.remove(0).as_string(); Ok(val.ends_with(&chr).into()) } pub fn join(_: &Runtime, mut args: Vec) -> Result { - let chr = args.remove(0).as_strand().value; - let val = args.into_iter().map(|x| x.as_strand().value); + let chr = args.remove(0).as_string(); + let val = args.into_iter().map(|x| x.as_string()); let val = val.collect::>().join(&chr); Ok(val.into()) } pub fn length(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); let num = val.chars().count() as i64; Ok(num.into()) } pub fn lowercase(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.to_lowercase().into()) + Ok(args.remove(0).as_string().to_lowercase().into()) } pub fn repeat(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); let num = args.remove(0).as_int() as usize; Ok(val.repeat(num).into()) } pub fn replace(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; - let old = args.remove(0).as_strand().value; - let new = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); + let old = args.remove(0).as_string(); + let new = args.remove(0).as_string(); Ok(val.replace(&old, &new).into()) } pub fn reverse(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.chars().rev().collect::().into()) + Ok(args.remove(0).as_string().chars().rev().collect::().into()) } pub fn slice(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); let beg = args.remove(0).as_int() as usize; let lim = args.remove(0).as_int() as usize; let val = val.chars().skip(beg).take(lim).collect::(); @@ -56,30 +56,30 @@ pub fn slice(_: &Runtime, mut args: Vec) -> Result { } pub fn slug(_: &Runtime, mut args: Vec) -> Result { - Ok(slugify(&args.remove(0).as_strand().value).into()) + Ok(slugify(&args.remove(0).as_string()).into()) } pub fn split(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; - let chr = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); + let chr = args.remove(0).as_string(); let val = val.split(&chr).collect::>(); Ok(val.into()) } pub fn starts_with(_: &Runtime, mut args: Vec) -> Result { - let val = args.remove(0).as_strand().value; - let chr = args.remove(0).as_strand().value; + let val = args.remove(0).as_string(); + let chr = args.remove(0).as_string(); Ok(val.starts_with(&chr).into()) } pub fn trim(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.trim().into()) + Ok(args.remove(0).as_string().trim().into()) } pub fn uppercase(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.to_uppercase().into()) + Ok(args.remove(0).as_string().to_uppercase().into()) } pub fn words(_: &Runtime, mut args: Vec) -> Result { - Ok(args.remove(0).as_strand().value.split(' ').collect::>().into()) + Ok(args.remove(0).as_string().split(' ').collect::>().into()) } diff --git a/lib/src/fnc/time.rs b/lib/src/fnc/time.rs index 9e062bf2..c7099f74 100644 --- a/lib/src/fnc/time.rs +++ b/lib/src/fnc/time.rs @@ -37,7 +37,7 @@ pub fn floor(_: &Runtime, mut args: Vec) -> Result { pub fn group(_: &Runtime, mut args: Vec) -> Result { match args.remove(0) { Value::Datetime(v) => match args.remove(0) { - Value::Strand(g) => match g.value.as_str() { + Value::Strand(g) => match g.as_str() { "year" => Ok(Utc.ymd(v.value.year(), 1, 1).and_hms(0, 0, 0).into()), "month" => Ok(Utc.ymd(v.value.year(), v.value.month(), 1).and_hms(0, 0, 0).into()), "day" => Ok(Utc diff --git a/lib/src/fnc/type.rs b/lib/src/fnc/type.rs index 27caca87..dc2611f1 100644 --- a/lib/src/fnc/type.rs +++ b/lib/src/fnc/type.rs @@ -100,12 +100,12 @@ pub fn thing(_: &Runtime, mut args: Vec) -> Result { let tb = args.remove(0); match args.remove(0) { Value::Thing(id) => Ok(Value::Thing(Thing { - tb: tb.as_strand().value, + tb: tb.as_string(), id: id.id, })), id => Ok(Value::Thing(Thing { - tb: tb.as_strand().value, - id: id.as_strand().into(), + tb: tb.as_string(), + id: id.as_string().into(), })), } } diff --git a/lib/src/sql/id.rs b/lib/src/sql/id.rs index 9e284e5c..1ca3f4d2 100644 --- a/lib/src/sql/id.rs +++ b/lib/src/sql/id.rs @@ -4,7 +4,6 @@ use crate::sql::common::val_char; use crate::sql::error::IResult; use crate::sql::ident::ident_raw; use crate::sql::number::{number, Number}; -use crate::sql::strand::Strand; use nanoid::nanoid; use nom::branch::alt; use nom::combinator::map; @@ -29,12 +28,6 @@ impl From for Id { } } -impl From for Id { - fn from(v: Strand) -> Self { - Id::String(v.value) - } -} - impl From<&str> for Id { fn from(v: &str) -> Self { Id::String(v.to_owned()) diff --git a/lib/src/sql/operation.rs b/lib/src/sql/operation.rs index 4bc48b51..3f307f6f 100644 --- a/lib/src/sql/operation.rs +++ b/lib/src/sql/operation.rs @@ -26,7 +26,7 @@ impl Default for Op { impl From<&Value> for Op { fn from(v: &Value) -> Self { - match &v.to_strand().value[..] { + match v.to_strand().as_str() { "add" => Op::Add, "remove" => Op::Remove, "replace" => Op::Replace, diff --git a/lib/src/sql/strand.rs b/lib/src/sql/strand.rs index 43d718e6..550d5063 100644 --- a/lib/src/sql/strand.rs +++ b/lib/src/sql/strand.rs @@ -4,10 +4,10 @@ use nom::bytes::complete::escaped; use nom::bytes::complete::is_not; use nom::bytes::complete::tag; use nom::character::complete::one_of; -use serde::ser::SerializeStruct; use serde::{Deserialize, Serialize}; use std::fmt; use std::ops; +use std::ops::Deref; use std::str; const SINGLE: &str = r#"'"#; @@ -17,35 +17,39 @@ const DOUBLE: &str = r#"""#; const DOUBLE_ESC: &str = r#"\""#; #[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize)] -pub struct Strand { - pub value: String, -} +pub struct Strand(pub String); impl From for Strand { fn from(s: String) -> Self { - Strand { - value: s, - } + Strand(s) } } impl<'a> From<&'a str> for Strand { fn from(s: &str) -> Self { - Strand { - value: String::from(s), - } + Strand(String::from(s)) + } +} + +impl Deref for Strand { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 } } impl Strand { pub fn as_str(&self) -> &str { - self.value.as_str() + self.0.as_str() + } + pub fn as_string(self) -> String { + self.0 } } impl fmt::Display for Strand { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "\"{}\"", self.value) + write!(f, "\"{}\"", self.0) } } @@ -55,11 +59,9 @@ impl Serialize for Strand { S: serde::Serializer, { if serializer.is_human_readable() { - serializer.serialize_some(&self.value) + serializer.serialize_some(&self.0) } else { - let mut val = serializer.serialize_struct("Strand", 1)?; - val.serialize_field("value", &self.value)?; - val.end() + serializer.serialize_newtype_struct("Strand", &self.0) } } } @@ -67,13 +69,13 @@ impl Serialize for Strand { impl ops::Add for Strand { type Output = Self; fn add(self, other: Self) -> Self { - Strand::from(self.value + &other.value) + Strand::from(self.0 + &other.0) } } pub fn strand(i: &str) -> IResult<&str, Strand> { let (i, v) = strand_raw(i)?; - Ok((i, Strand::from(v))) + Ok((i, Strand(v))) } pub fn strand_raw(i: &str) -> IResult<&str, String> { diff --git a/lib/src/sql/table.rs b/lib/src/sql/table.rs index 02dedd3c..9e5fdcca 100644 --- a/lib/src/sql/table.rs +++ b/lib/src/sql/table.rs @@ -3,7 +3,6 @@ use crate::sql::common::escape; use crate::sql::common::val_char; use crate::sql::error::IResult; use crate::sql::ident::ident_raw; -use crate::sql::strand::Strand; use nom::multi::separated_list1; use serde::{Deserialize, Serialize}; use std::fmt; @@ -33,12 +32,6 @@ impl From for Table { } } -impl From for Table { - fn from(v: Strand) -> Self { - Table(v.value) - } -} - impl Deref for Table { type Target = String; fn deref(&self) -> &Self::Target { diff --git a/lib/src/sql/value/diff.rs b/lib/src/sql/value/diff.rs index e60b8396..b9ab197d 100644 --- a/lib/src/sql/value/diff.rs +++ b/lib/src/sql/value/diff.rs @@ -66,7 +66,7 @@ impl Value { path, value: { let mut dmp = dmp::new(); - let mut pch = dmp.patch_make1(&a.value, &b.value); + let mut pch = dmp.patch_make1(a, b); let txt = dmp.patch_to_text(&mut pch); txt.into() }, diff --git a/lib/src/sql/value/patch.rs b/lib/src/sql/value/patch.rs index 3358b59f..69a867ba 100644 --- a/lib/src/sql/value/patch.rs +++ b/lib/src/sql/value/patch.rs @@ -26,8 +26,8 @@ impl Value { if let Value::Strand(p) = o.value { if let Value::Strand(v) = self.get(ctx, opt, txn, &o.path).await? { let mut dmp = dmp::new(); - let mut pch = dmp.patch_from_text(p.value); - let (txt, _) = dmp.patch_apply(&mut pch, &v.value); + let mut pch = dmp.patch_from_text(p.as_string()); + let (txt, _) = dmp.patch_apply(&mut pch, v.as_str()); let txt = txt.into_iter().collect::(); self.set(ctx, opt, txn, &o.path, Value::from(txt)).await?; } diff --git a/lib/src/sql/value/value.rs b/lib/src/sql/value/value.rs index f68896dc..a26e205a 100644 --- a/lib/src/sql/value/value.rs +++ b/lib/src/sql/value/value.rs @@ -479,7 +479,7 @@ impl Value { pub fn is_true(&self) -> bool { match self { Value::True => true, - Value::Strand(v) => v.value.to_ascii_lowercase() == "true", + Value::Strand(v) => v.to_ascii_lowercase() == "true", _ => false, } } @@ -487,7 +487,7 @@ impl Value { pub fn is_false(&self) -> bool { match self { Value::False => true, - Value::Strand(v) => v.value.to_ascii_lowercase() == "false", + Value::Strand(v) => v.to_ascii_lowercase() == "false", _ => false, } } @@ -500,7 +500,7 @@ impl Value { Value::Geometry(_) => true, Value::Array(v) => !v.is_empty(), Value::Object(v) => !v.is_empty(), - Value::Strand(v) => !v.value.is_empty() && v.value.to_ascii_lowercase() != "false", + Value::Strand(v) => !v.is_empty() && v.to_ascii_lowercase() != "false", Value::Number(v) => v.is_truthy(), Value::Duration(v) => v.value.as_nanos() > 0, Value::Datetime(v) => v.value.timestamp() > 0, @@ -549,7 +549,7 @@ impl Value { pub fn as_int(self) -> i64 { match self { Value::True => 1, - Value::Strand(v) => v.value.parse::().unwrap_or(0), + Value::Strand(v) => v.parse::().unwrap_or(0), Value::Number(v) => v.as_int(), Value::Duration(v) => v.value.as_secs() as i64, Value::Datetime(v) => v.value.timestamp(), @@ -560,7 +560,7 @@ impl Value { pub fn as_float(self) -> f64 { match self { Value::True => 1.0, - Value::Strand(v) => v.value.parse::().unwrap_or(0.0), + Value::Strand(v) => v.parse::().unwrap_or(0.0), Value::Number(v) => v.as_float(), Value::Duration(v) => v.value.as_secs() as f64, Value::Datetime(v) => v.value.timestamp() as f64, @@ -590,13 +590,6 @@ impl Value { } } - pub fn as_string(self) -> String { - match self { - Value::Strand(v) => v.value, - _ => self.to_string(), - } - } - pub fn as_strand(self) -> Strand { match self { Value::Strand(v) => v, @@ -620,6 +613,13 @@ impl Value { } } + pub fn as_string(self) -> String { + match self { + Value::Strand(v) => v.as_string(), + _ => self.to_string(), + } + } + // ----------------------------------- // Expensive conversion of value // ----------------------------------- @@ -660,7 +660,7 @@ impl Value { pub fn to_idiom(&self) -> Idiom { self.to_strand() - .value + .as_str() .trim_start_matches('/') .split(&['.', '/'][..]) .map(Part::from) @@ -854,7 +854,7 @@ impl Value { match self { Value::Strand(v) => match other { Value::Strand(w) => MATCHER.fuzzy_match(v.as_str(), w.as_str()).is_some(), - _ => MATCHER.fuzzy_match(v.as_str(), other.to_strand().as_str()).is_some(), + _ => MATCHER.fuzzy_match(v.as_str(), other.to_string().as_str()).is_some(), }, _ => self.equal(other), } @@ -878,8 +878,8 @@ impl Value { match self { Value::Array(v) => v.iter().any(|v| v.equal(other)), Value::Strand(v) => match other { - Value::Strand(w) => v.value.contains(w.as_str()), - _ => v.value.contains(&other.to_strand().as_str()), + Value::Strand(w) => v.contains(w.as_str()), + _ => v.contains(&other.to_string().as_str()), }, Value::Geometry(v) => match other { Value::Geometry(w) => v.contains(w), @@ -927,27 +927,21 @@ impl Value { pub fn lexical_cmp(&self, other: &Value) -> Option { match (self, other) { - (Value::Strand(a), Value::Strand(b)) => { - Some(lexical_sort::lexical_cmp(&a.value, &b.value)) - } + (Value::Strand(a), Value::Strand(b)) => Some(lexical_sort::lexical_cmp(a, b)), _ => self.partial_cmp(other), } } pub fn natural_cmp(&self, other: &Value) -> Option { match (self, other) { - (Value::Strand(a), Value::Strand(b)) => { - Some(lexical_sort::natural_cmp(&a.value, &b.value)) - } + (Value::Strand(a), Value::Strand(b)) => Some(lexical_sort::natural_cmp(a, b)), _ => self.partial_cmp(other), } } pub fn natural_lexical_cmp(&self, other: &Value) -> Option { match (self, other) { - (Value::Strand(a), Value::Strand(b)) => { - Some(lexical_sort::natural_lexical_cmp(&a.value, &b.value)) - } + (Value::Strand(a), Value::Strand(b)) => Some(lexical_sort::natural_lexical_cmp(a, b)), _ => self.partial_cmp(other), } } @@ -1330,6 +1324,24 @@ mod tests { assert_eq!(Strand::from("something"), Value::from("something").as_strand()); } + #[test] + fn convert_string() { + assert_eq!(String::from("NONE"), Value::None.as_string()); + assert_eq!(String::from("NULL"), Value::Null.as_string()); + assert_eq!(String::from("VOID"), Value::Void.as_string()); + assert_eq!(String::from("true"), Value::True.as_string()); + assert_eq!(String::from("false"), Value::False.as_string()); + assert_eq!(String::from("0"), Value::from(0).as_string()); + assert_eq!(String::from("1"), Value::from(1).as_string()); + assert_eq!(String::from("-1"), Value::from(-1).as_string()); + assert_eq!(String::from("1.1"), Value::from(1.1).as_string()); + assert_eq!(String::from("-1.1"), Value::from(-1.1).as_string()); + assert_eq!(String::from("3"), Value::from("3").as_string()); + assert_eq!(String::from("true"), Value::from("true").as_string()); + assert_eq!(String::from("false"), Value::from("false").as_string()); + assert_eq!(String::from("something"), Value::from("something").as_string()); + } + #[test] fn serialize_deserialize() { let val = Value::parse(