Refactor, optimization, and cleanup of code (#71)

This commit is contained in:
Finn Bear 2022-08-28 18:47:33 -07:00 committed by GitHub
parent 42d8260966
commit b18b3cef3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 84 deletions

View file

@ -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> {

View file

@ -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())
}

View file

@ -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

View file

@ -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
});
}
}

View file

@ -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(())
}
}

View file

@ -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()
}
}

View file

@ -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(())
}
_ => {