mod conversion;
mod datetime;
mod hash;
mod math;
#[cfg(feature = "semantic")]
pub mod semantic;
mod string;
mod utility;
pub mod vector;
pub use conversion::{CastFunction, CollateFunction};
pub use datetime::{
CurrentDateFunction, CurrentTimeFunction, CurrentTimestampFunction, DateAddFunction,
DateDiffAliasFunction, DateDiffFunction, DateSubFunction, DateTruncFunction, DayFunction,
ExtractFunction, HourFunction, MinuteFunction, MonthFunction, SecondFunction,
TimeTruncFunction, ToCharFunction, VersionFunction, YearFunction,
};
pub use hash::{
Crc32Function, Md5Function, Sha1Function, Sha256Function, Sha384Function, Sha512Function,
};
pub use math::{
AbsFunction, CeilFunction, CeilingFunction, CosFunction, ExpFunction, FloorFunction,
LnFunction, Log10Function, Log2Function, LogFunction, ModFunction, PiFunction, PowFunction,
PowerFunction, RandomFunction, RoundFunction, SignFunction, SinFunction, SqrtFunction,
TanFunction, TruncFunction, TruncateFunction,
};
pub use string::{
CharFunction, CharLengthFunction, ConcatFunction, ConcatWsFunction, ContainsFunction,
EndsWithFunction, InstrFunction, LeftFunction, LengthFunction, LocateFunction, LowerFunction,
LpadFunction, LtrimFunction, PositionFunction, RepeatFunction, ReplaceFunction,
ReverseFunction, RightFunction, RpadFunction, RtrimFunction, SplitPartFunction,
StartsWithFunction, StrposFunction, SubstrFunction, SubstringFunction, TrimFunction,
UpperFunction,
};
pub use utility::{
CoalesceFunction, GreatestFunction, IfNullFunction, IifFunction, JsonArrayFunction,
JsonArrayLengthFunction, JsonExtractFunction, JsonKeysFunction, JsonObjectFunction,
JsonTypeFunction, JsonTypeOfFunction, JsonValidFunction, LeastFunction, NowFunction,
NullIfFunction, SleepFunction, TypeOfFunction,
};
use crate::core::{DataType, Value};
#[macro_export]
macro_rules! validate_arg_count {
($args:expr, $name:expr, $exact:expr) => {
if $args.len() != $exact {
return Err($crate::core::Error::invalid_argument(format!(
"{} requires exactly {} argument{}, got {}",
$name,
$exact,
if $exact == 1 { "" } else { "s" },
$args.len()
)));
}
};
($args:expr, $name:expr, $min:expr, $max:expr) => {
if $args.len() < $min || $args.len() > $max {
return Err($crate::core::Error::invalid_argument(format!(
"{} requires {} to {} arguments, got {}",
$name,
$min,
$max,
$args.len()
)));
}
};
}
#[inline]
pub fn value_as_str(value: &Value) -> Option<&str> {
match value {
Value::Text(s) => Some(s.as_ref()),
_ => None,
}
}
pub fn value_to_string(value: &Value) -> String {
if value.is_null() {
return String::new();
}
match value {
Value::Null(_) => String::new(),
Value::Integer(i) => i.to_string(),
Value::Float(f) => f.to_string(),
Value::Text(s) => s.to_string(),
Value::Boolean(b) => b.to_string(),
Value::Timestamp(t) => t.to_rfc3339(),
Value::Extension(data) if data.first() == Some(&(DataType::Json as u8)) => {
std::str::from_utf8(&data[1..]).unwrap_or("").to_string()
}
Value::Extension(data) if data.first() == Some(&(DataType::Vector as u8)) => {
crate::core::value::format_vector_bytes(&data[1..])
}
Value::Extension(_) => String::new(),
}
}
pub fn value_to_f64(value: &Value) -> Option<f64> {
match value {
Value::Integer(i) => Some(*i as f64),
Value::Float(f) => Some(*f),
Value::Text(s) => s.parse().ok(),
_ => None,
}
}
pub fn value_to_i64(value: &Value) -> Option<i64> {
match value {
Value::Integer(i) => Some(*i),
Value::Float(f) => Some(*f as i64),
Value::Text(s) => s.parse().ok(),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_value_to_string() {
assert_eq!(value_to_string(&Value::Integer(42)), "42");
assert_eq!(value_to_string(&Value::Float(3.5)), "3.5");
assert_eq!(value_to_string(&Value::text("hello")), "hello");
assert_eq!(value_to_string(&Value::Boolean(true)), "true");
assert_eq!(value_to_string(&Value::null_unknown()), "");
}
#[test]
fn test_value_to_f64() {
assert_eq!(value_to_f64(&Value::Integer(42)), Some(42.0));
assert_eq!(value_to_f64(&Value::Float(3.5)), Some(3.5));
assert_eq!(value_to_f64(&Value::text("2.5")), Some(2.5));
assert_eq!(value_to_f64(&Value::null_unknown()), None);
}
#[test]
fn test_value_to_i64() {
assert_eq!(value_to_i64(&Value::Integer(42)), Some(42));
assert_eq!(value_to_i64(&Value::Float(3.7)), Some(3));
assert_eq!(value_to_i64(&Value::text("100")), Some(100));
assert_eq!(value_to_i64(&Value::null_unknown()), None);
}
}