mod conversion;
mod datetime;
mod math;
mod string;
mod utility;
pub use conversion::{CastFunction, CollateFunction};
pub use datetime::{
CurrentDateFunction, CurrentTimestampFunction, DateAddFunction, DateDiffAliasFunction,
DateDiffFunction, DateSubFunction, DateTruncFunction, DayFunction, ExtractFunction,
HourFunction, MinuteFunction, MonthFunction, SecondFunction, TimeTruncFunction, ToCharFunction,
VersionFunction, YearFunction,
};
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, InstrFunction,
LeftFunction, LengthFunction, LocateFunction, LowerFunction, LpadFunction, LtrimFunction,
PositionFunction, RepeatFunction, ReplaceFunction, ReverseFunction, RightFunction,
RpadFunction, RtrimFunction, SplitPartFunction, StrposFunction, SubstrFunction,
SubstringFunction, TrimFunction, UpperFunction,
};
pub use utility::{
CoalesceFunction, GetHttpHeaderFunction, GreatestFunction, IfNullFunction, IifFunction,
JsonArrayFunction, JsonArrayLengthFunction, JsonExtractFunction, JsonKeysFunction,
JsonObjectFunction, JsonTypeFunction, JsonTypeOfFunction, JsonValidFunction, LeastFunction,
NowFunction, NullIfFunction, SleepFunction, TypeOfFunction,
};
use crate::core::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()
)));
}
};
}
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::Json(j) => j.to_string(),
}
}
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);
}
}