Refactor, optimization, and cleanup of code (#71)
This commit is contained in:
parent
42d8260966
commit
b18b3cef3e
7 changed files with 66 additions and 84 deletions
|
@ -6,6 +6,7 @@ use crate::sql::uuid::Uuid;
|
|||
use crate::sql::value::Value;
|
||||
use nanoid::nanoid;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::prelude::IteratorRandom;
|
||||
use rand::Rng;
|
||||
|
||||
pub fn rand(_: &Context, _: Vec<Value>) -> Result<Value, Error> {
|
||||
|
@ -17,23 +18,14 @@ pub fn bool(_: &Context, _: Vec<Value>) -> Result<Value, Error> {
|
|||
}
|
||||
|
||||
pub fn r#enum(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
match args.len() {
|
||||
0 => Ok(Value::None),
|
||||
Ok(match args.len() {
|
||||
0 => Value::None,
|
||||
1 => match args.remove(0) {
|
||||
Value::Array(mut v) => match v.len() {
|
||||
0 => Ok(Value::None),
|
||||
n => {
|
||||
let i = rand::thread_rng().gen_range(0..n);
|
||||
Ok(v.remove(i))
|
||||
}
|
||||
Value::Array(v) => v.into_iter().choose(&mut rand::thread_rng()).unwrap_or(Value::None),
|
||||
v => v,
|
||||
},
|
||||
v => Ok(v),
|
||||
},
|
||||
n => {
|
||||
let i = rand::thread_rng().gen_range(0..n);
|
||||
Ok(args.remove(i))
|
||||
}
|
||||
}
|
||||
_ => args.into_iter().choose(&mut rand::thread_rng()).unwrap(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn float(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
|
|
|
@ -7,16 +7,18 @@ pub fn concat(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
|||
Ok(args.into_iter().map(|x| x.as_string()).collect::<Vec<_>>().concat().into())
|
||||
}
|
||||
|
||||
pub fn ends_with(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
let val = args.remove(0).as_string();
|
||||
let chr = args.remove(0).as_string();
|
||||
pub fn ends_with(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let args: [Value; 2] = args.try_into().unwrap();
|
||||
let [val, chr] = args.map(Value::as_string);
|
||||
Ok(val.ends_with(&chr).into())
|
||||
}
|
||||
|
||||
pub fn join(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
let chr = args.remove(0).as_string();
|
||||
let val = args.into_iter().map(|x| x.as_string());
|
||||
let val = val.collect::<Vec<_>>().join(&chr);
|
||||
pub fn join(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let mut args = args.into_iter().map(Value::as_string);
|
||||
let chr = args.next().unwrap();
|
||||
// FIXME: Use intersperse to avoid intermediate allocation once stable
|
||||
// https://github.com/rust-lang/rust/issues/79524
|
||||
let val = args.collect::<Vec<_>>().join(&chr);
|
||||
Ok(val.into())
|
||||
}
|
||||
|
||||
|
@ -30,16 +32,16 @@ pub fn lowercase(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
|||
Ok(args.remove(0).as_string().to_lowercase().into())
|
||||
}
|
||||
|
||||
pub fn repeat(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
let val = args.remove(0).as_string();
|
||||
let num = args.remove(0).as_int() as usize;
|
||||
pub fn repeat(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let [val_arg, num_arg]: [Value; 2] = args.try_into().unwrap();
|
||||
let val = val_arg.as_string();
|
||||
let num = num_arg.as_int() as usize;
|
||||
Ok(val.repeat(num).into())
|
||||
}
|
||||
|
||||
pub fn replace(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
let val = args.remove(0).as_string();
|
||||
let old = args.remove(0).as_string();
|
||||
let new = args.remove(0).as_string();
|
||||
pub fn replace(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let args: [Value; 3] = args.try_into().unwrap();
|
||||
let [val, old, new] = args.map(Value::as_string);
|
||||
Ok(val.replace(&old, &new).into())
|
||||
}
|
||||
|
||||
|
@ -47,10 +49,11 @@ pub fn reverse(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
|||
Ok(args.remove(0).as_string().chars().rev().collect::<String>().into())
|
||||
}
|
||||
|
||||
pub fn slice(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
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;
|
||||
pub fn slice(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let [val_arg, beg_arg, lim_arg]: [Value; 3] = args.try_into().unwrap();
|
||||
let val = val_arg.as_string();
|
||||
let beg = beg_arg.as_int() as usize;
|
||||
let lim = lim_arg.as_int() as usize;
|
||||
let val = val.chars().skip(beg).take(lim).collect::<String>();
|
||||
Ok(val.into())
|
||||
}
|
||||
|
@ -59,16 +62,16 @@ pub fn slug(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
|||
Ok(string::slug(&args.remove(0).as_string()).into())
|
||||
}
|
||||
|
||||
pub fn split(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
let val = args.remove(0).as_string();
|
||||
let chr = args.remove(0).as_string();
|
||||
pub fn split(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let args: [Value; 2] = args.try_into().unwrap();
|
||||
let [val, chr] = args.map(Value::as_string);
|
||||
let val = val.split(&chr).collect::<Vec<&str>>();
|
||||
Ok(val.into())
|
||||
}
|
||||
|
||||
pub fn starts_with(_: &Context, mut args: Vec<Value>) -> Result<Value, Error> {
|
||||
let val = args.remove(0).as_string();
|
||||
let chr = args.remove(0).as_string();
|
||||
pub fn starts_with(_: &Context, args: Vec<Value>) -> Result<Value, Error> {
|
||||
let args: [Value; 2] = args.try_into().unwrap();
|
||||
let [val, chr] = args.map(Value::as_string);
|
||||
Ok(val.starts_with(&chr).into())
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ pub fn slug<S: AsRef<str>>(s: S) -> String {
|
|||
// Get a reference
|
||||
let s = s.as_ref();
|
||||
// Convert unicode to ascii
|
||||
let s = deunicode(s);
|
||||
let mut s = deunicode(s);
|
||||
// Convert string to lowercase
|
||||
let s = s.to_ascii_lowercase();
|
||||
s.make_ascii_lowercase();
|
||||
// Replace any non-simple characters
|
||||
let s = SIMPLES.replace_all(s.as_ref(), "-");
|
||||
// Replace any duplicated hyphens
|
||||
|
|
|
@ -206,22 +206,14 @@ impl<T> Abolish<T> for Vec<T> {
|
|||
where
|
||||
F: FnMut(usize) -> bool,
|
||||
{
|
||||
let len = self.len();
|
||||
let mut del = 0;
|
||||
{
|
||||
let v = &mut **self;
|
||||
|
||||
for i in 0..len {
|
||||
if f(i) {
|
||||
del += 1;
|
||||
} else if del > 0 {
|
||||
v.swap(i - del, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if del > 0 {
|
||||
self.truncate(len - del);
|
||||
}
|
||||
let mut i = 0;
|
||||
// FIXME: use drain_filter once stabilized (https://github.com/rust-lang/rust/issues/43244)
|
||||
// to avoid negation of the predicate return value.
|
||||
self.retain(|_| {
|
||||
let retain = !f(i);
|
||||
i += 1;
|
||||
retain
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,7 @@ impl From<time::Duration> for Duration {
|
|||
|
||||
impl From<String> for Duration {
|
||||
fn from(s: String) -> Self {
|
||||
match duration(s.as_ref()) {
|
||||
Ok((_, v)) => v,
|
||||
Err(_) => Duration::default(),
|
||||
}
|
||||
s.as_str().into()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +61,12 @@ impl fmt::Display for Duration {
|
|||
// Split up the duration
|
||||
let secs = self.0.as_secs();
|
||||
let nano = self.0.subsec_nanos();
|
||||
|
||||
// Ensure no empty output
|
||||
if secs == 0 && nano == 0 {
|
||||
return write!(f, "0ns");
|
||||
}
|
||||
|
||||
// Calculate the total years
|
||||
let year = secs / SECONDS_PER_YEAR;
|
||||
let secs = secs % SECONDS_PER_YEAR;
|
||||
|
@ -79,36 +82,29 @@ impl fmt::Display for Duration {
|
|||
// Calculate the total mins
|
||||
let mins = secs / SECONDS_PER_MINUTE;
|
||||
let secs = secs % SECONDS_PER_MINUTE;
|
||||
// Prepare the outpit
|
||||
let mut o = Vec::with_capacity(7);
|
||||
// Write the different parts
|
||||
if year > 0 {
|
||||
o.push(format!("{year}y"));
|
||||
write!(f, "{year}y")?;
|
||||
}
|
||||
if week > 0 {
|
||||
o.push(format!("{week}w"));
|
||||
write!(f, "{week}w")?;
|
||||
}
|
||||
if days > 0 {
|
||||
o.push(format!("{days}d"));
|
||||
write!(f, "{days}d")?;
|
||||
}
|
||||
if hour > 0 {
|
||||
o.push(format!("{hour}h"));
|
||||
write!(f, "{hour}h")?;
|
||||
}
|
||||
if mins > 0 {
|
||||
o.push(format!("{mins}m"));
|
||||
write!(f, "{mins}m")?;
|
||||
}
|
||||
if secs > 0 {
|
||||
o.push(format!("{secs}s"));
|
||||
write!(f, "{secs}s")?;
|
||||
}
|
||||
if nano > 0 {
|
||||
o.push(format!("{nano}ns"));
|
||||
write!(f, "{nano}ns")?;
|
||||
}
|
||||
// Ensure no empty output
|
||||
if o.is_empty() {
|
||||
o.push("0ns".to_string());
|
||||
}
|
||||
// Concatenate together
|
||||
write!(f, "{}", o.concat())
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,10 +32,7 @@ impl fmt::Display for Regex {
|
|||
|
||||
impl Regex {
|
||||
pub fn regex(&self) -> Option<regex::Regex> {
|
||||
match regex::Regex::new(&self.0) {
|
||||
Ok(v) => Some(v),
|
||||
Err(_) => None,
|
||||
}
|
||||
regex::Regex::new(&self.0).ok()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::sql::part::Part;
|
|||
use crate::sql::value::Value;
|
||||
use async_recursion::async_recursion;
|
||||
use futures::future::try_join_all;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
|
||||
impl Value {
|
||||
#[cfg_attr(feature = "parallel", async_recursion)]
|
||||
|
@ -91,13 +91,15 @@ impl Value {
|
|||
},
|
||||
Part::Where(w) => match path.len() {
|
||||
1 => {
|
||||
let mut m = HashMap::new();
|
||||
// TODO: If further optimization is desired, push indices to a vec,
|
||||
// iterate in reverse, and call swap_remove
|
||||
let mut m = HashSet::new();
|
||||
for (i, v) in v.iter().enumerate() {
|
||||
if w.compute(ctx, opt, txn, Some(v)).await?.is_truthy() {
|
||||
m.insert(i, ());
|
||||
m.insert(i);
|
||||
};
|
||||
}
|
||||
v.abolish(|i| m.contains_key(&i));
|
||||
v.abolish(|i| m.contains(&i));
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
|
|
Loading…
Reference in a new issue