use crate::err::Error; use crate::fnc::util::string; use crate::sql::value::Value; pub fn concat(args: Vec) -> Result { Ok(args.into_iter().map(|x| x.as_string()).collect::>().concat().into()) } pub fn ends_with((val, chr): (String, String)) -> Result { Ok(val.ends_with(&chr).into()) } pub fn join(args: Vec) -> Result { let mut args = args.into_iter().map(Value::as_string); let chr = args.next().ok_or(Error::InvalidArguments { name: String::from("string::join"), message: String::from("Expected at least one argument"), })?; // FIXME: Use intersperse to avoid intermediate allocation once stable // https://github.com/rust-lang/rust/issues/79524 let val = args.collect::>().join(&chr); Ok(val.into()) } pub fn length((string,): (String,)) -> Result { let num = string.chars().count() as i64; Ok(num.into()) } pub fn lowercase((string,): (String,)) -> Result { Ok(string.to_lowercase().into()) } pub fn repeat((val, num): (String, usize)) -> Result { const LIMIT: usize = 2usize.pow(20); if val.len().saturating_mul(num) > LIMIT { Err(Error::InvalidArguments { name: String::from("string::repeat"), message: format!("Output must not exceed {} bytes.", LIMIT), }) } else { Ok(val.repeat(num).into()) } } pub fn replace((val, old, new): (String, String, String)) -> Result { Ok(val.replace(&old, &new).into()) } pub fn reverse((string,): (String,)) -> Result { Ok(string.chars().rev().collect::().into()) } pub fn slice((val, beg, lim): (String, usize, usize)) -> Result { Ok(val.chars().skip(beg).take(lim).collect::().into()) } pub fn slug((string,): (String,)) -> Result { Ok(string::slug(&string).into()) } pub fn split((val, chr): (String, String)) -> Result { Ok(val.split(&chr).collect::>().into()) } pub fn starts_with((val, chr): (String, String)) -> Result { Ok(val.starts_with(&chr).into()) } pub fn trim((string,): (String,)) -> Result { Ok(string.trim().into()) } pub fn uppercase((string,): (String,)) -> Result { Ok(string.to_uppercase().into()) } pub fn words((string,): (String,)) -> Result { Ok(string.split_whitespace().collect::>().into()) }