2022-01-13 17:37:46 +00:00
|
|
|
use crate::err::Error;
|
|
|
|
use crate::sql::value::Value;
|
2023-11-27 19:14:41 +00:00
|
|
|
use crate::sql::{Array, Bytes, Datetime, Duration, Kind, Number, Object, Regex, Strand, Thing};
|
2022-01-13 17:37:46 +00:00
|
|
|
|
2022-09-21 00:57:33 +00:00
|
|
|
/// Implemented by types that are commonly used, in a certain way, as arguments.
|
|
|
|
pub trait FromArg: Sized {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for Value {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
|
|
|
Ok(arg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-20 18:36:21 +00:00
|
|
|
impl FromArg for Regex {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
|
|
|
arg.coerce_to_regex()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-21 00:57:33 +00:00
|
|
|
impl FromArg for String {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_string()
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for Strand {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_strand()
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for Number {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_number()
|
2023-04-25 10:13:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for Datetime {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_datetime()
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-10 15:24:27 +00:00
|
|
|
impl FromArg for Duration {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_duration()
|
2023-03-10 15:24:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-25 10:13:04 +00:00
|
|
|
impl FromArg for Thing {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_record()
|
2023-04-25 10:13:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for Array {
|
2022-09-21 00:57:33 +00:00
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_array()
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-27 19:14:41 +00:00
|
|
|
impl FromArg for Object {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
|
|
|
arg.coerce_to_object()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-09 20:43:16 +00:00
|
|
|
impl FromArg for Bytes {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_bytes()
|
2023-05-09 20:43:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-21 00:57:33 +00:00
|
|
|
impl FromArg for i64 {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_i64()
|
2023-04-25 10:13:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for u64 {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_u64()
|
2023-04-25 10:13:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl FromArg for f64 {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_f64()
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 11:05:33 +00:00
|
|
|
impl FromArg for isize {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
Ok(arg.coerce_to_i64()? as isize)
|
2022-11-27 11:05:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-21 00:57:33 +00:00
|
|
|
impl FromArg for usize {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
Ok(arg.coerce_to_u64()? as usize)
|
2023-04-25 10:13:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-31 12:06:10 +00:00
|
|
|
impl FromArg for Vec<String> {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
|
|
|
arg.coerce_to_array_type(&Kind::String)?.into_iter().map(Value::try_into).collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-25 10:13:04 +00:00
|
|
|
impl FromArg for Vec<Number> {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
2023-06-06 06:12:59 +00:00
|
|
|
arg.coerce_to_array_type(&Kind::Number)?.into_iter().map(Value::try_into).collect()
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-23 08:19:28 +00:00
|
|
|
impl FromArg for Vec<Datetime> {
|
|
|
|
fn from_arg(arg: Value) -> Result<Self, Error> {
|
|
|
|
arg.coerce_to_array_type(&Kind::Datetime)?.into_iter().map(Value::try_into).collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-21 00:57:33 +00:00
|
|
|
pub trait FromArgs: Sized {
|
|
|
|
/// Convert a collection of argument values into a certain argument format, failing if there are
|
|
|
|
/// too many or too few arguments, or if one of the arguments could not be converted.
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Take ownership of the raw arguments collection, and assume responsibility of validating the
|
|
|
|
// number of arguments and converting them as necessary.
|
|
|
|
impl FromArgs for Vec<Value> {
|
|
|
|
fn from_args(_name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
Ok(args)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-27 10:40:49 +00:00
|
|
|
impl FromArgs for Vec<Array> {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
args.into_iter()
|
|
|
|
.enumerate()
|
|
|
|
.map(|(i, arg)| {
|
|
|
|
arg.coerce_to_array_type(&Kind::Any).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument {} was the wrong type. {e}", i + 1),
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-23 09:42:59 +00:00
|
|
|
/// Some functions take a fixed number of arguments.
|
|
|
|
/// The len must match the number of type idents that follow.
|
2022-09-21 00:57:33 +00:00
|
|
|
macro_rules! impl_tuple {
|
|
|
|
($len:expr, $( $T:ident ),*) => {
|
|
|
|
impl<$($T:FromArg),*> FromArgs for ($($T,)*) {
|
|
|
|
#[allow(non_snake_case)]
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let [$($T),*]: [Value; $len] = args.try_into().map_err(|_| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
// This match will be optimized away.
|
|
|
|
message: match $len {
|
|
|
|
0 => String::from("Expected no arguments."),
|
|
|
|
1 => String::from("Expected 1 argument."),
|
|
|
|
_ => format!("Expected {} arguments.", $len),
|
|
|
|
}
|
|
|
|
})?;
|
2023-04-25 10:13:04 +00:00
|
|
|
#[allow(unused_mut, unused_variables)]
|
|
|
|
let mut i = 0;
|
|
|
|
Ok((
|
|
|
|
$({
|
|
|
|
i += 1;
|
|
|
|
$T::from_arg($T).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument {i} was the wrong type. {e}"),
|
|
|
|
})?
|
|
|
|
},)*
|
|
|
|
))
|
2022-09-21 00:57:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// It is possible to add larger sequences to support higher quantities of fixed arguments.
|
|
|
|
impl_tuple!(0,);
|
|
|
|
impl_tuple!(1, A);
|
|
|
|
impl_tuple!(2, A, B);
|
|
|
|
impl_tuple!(3, A, B, C);
|
|
|
|
|
|
|
|
// Some functions take a single, optional argument, or no arguments at all.
|
|
|
|
impl<A: FromArg> FromArgs for (Option<A>,) {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let err = || Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: String::from("Expected 0 or 1 arguments."),
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
let mut args = args.into_iter();
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the first function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let a = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(a) => Some(A::from_arg(a).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 1 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process additional function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
if args.next().is_some() {
|
2023-04-25 10:13:04 +00:00
|
|
|
// Too many arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
return Err(err());
|
|
|
|
}
|
|
|
|
Ok((a,))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Some functions take 1 or 2 arguments, so the second argument is optional.
|
|
|
|
impl<A: FromArg, B: FromArg> FromArgs for (A, Option<B>) {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let err = || Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: String::from("Expected 1 or 2 arguments."),
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
let mut args = args.into_iter();
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the first argument
|
|
|
|
let a = A::from_arg(args.next().ok_or_else(err)?).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 1 was the wrong type. {e}"),
|
|
|
|
})?;
|
2022-09-21 00:57:33 +00:00
|
|
|
let b = match args.next() {
|
|
|
|
Some(b) => Some(B::from_arg(b)?),
|
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process additional function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
if args.next().is_some() {
|
2023-04-25 10:13:04 +00:00
|
|
|
// Too many arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
return Err(err());
|
|
|
|
}
|
|
|
|
Ok((a, b))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-12-17 21:03:13 +00:00
|
|
|
// Some functions take 2 or 3 arguments, so the third argument is optional.
|
|
|
|
impl<A: FromArg, B: FromArg, C: FromArg> FromArgs for (A, B, Option<C>) {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let err = || Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: String::from("Expected 2 or 3 arguments."),
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the function arguments
|
2022-12-17 21:03:13 +00:00
|
|
|
let mut args = args.into_iter();
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the first function argument
|
|
|
|
let a = A::from_arg(args.next().ok_or_else(err)?).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 1 was the wrong type. {e}"),
|
|
|
|
})?;
|
|
|
|
// Process the second function argument
|
|
|
|
let b = B::from_arg(args.next().ok_or_else(err)?).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 2 was the wrong type. {e}"),
|
|
|
|
})?;
|
|
|
|
// Process the third function argument
|
2022-12-17 21:03:13 +00:00
|
|
|
let c = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(c) => Some(C::from_arg(c).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 3 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-12-17 21:03:13 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process additional function arguments
|
2022-12-17 21:03:13 +00:00
|
|
|
if args.next().is_some() {
|
2023-04-25 10:13:04 +00:00
|
|
|
// Too many arguments
|
2022-12-17 21:03:13 +00:00
|
|
|
return Err(err());
|
|
|
|
}
|
|
|
|
Ok((a, b, c))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-21 00:57:33 +00:00
|
|
|
// Some functions take 0, 1, or 2 arguments, so both arguments are optional.
|
|
|
|
// It is safe to assume that, if the first argument is None, the second argument will also be None.
|
|
|
|
impl<A: FromArg, B: FromArg> FromArgs for (Option<A>, Option<B>) {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let err = || Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: String::from("Expected 0, 1, or 2 arguments."),
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
let mut args = args.into_iter();
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the first function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let a = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(a) => Some(A::from_arg(a).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 1 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the second function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let b = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(b) => Some(B::from_arg(b).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 2 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process additional function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
if args.next().is_some() {
|
2023-04-25 10:13:04 +00:00
|
|
|
// Too many arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
return Err(err());
|
|
|
|
}
|
|
|
|
Ok((a, b))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Some functions optionally take 2 arguments, or don't take any at all.
|
|
|
|
impl<A: FromArg, B: FromArg> FromArgs for (Option<(A, B)>,) {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let err = || Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: String::from("Expected 0 or 2 arguments."),
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
let mut args = args.into_iter();
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the first function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let a = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(a) => Some(A::from_arg(a).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 1 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the second function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let b = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(b) => Some(B::from_arg(b).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 2 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process additional function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
if a.is_some() != b.is_some() || args.next().is_some() {
|
2023-04-25 10:13:04 +00:00
|
|
|
// One argument, or too many arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
return Err(err());
|
|
|
|
}
|
|
|
|
Ok((a.zip(b),))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Some functions take 1, 2, or 3 arguments. It is safe to assume that, if the second argument is
|
|
|
|
// None, the third argument will also be None.
|
|
|
|
impl<A: FromArg, B: FromArg, C: FromArg> FromArgs for (A, Option<B>, Option<C>) {
|
|
|
|
fn from_args(name: &str, args: Vec<Value>) -> Result<Self, Error> {
|
|
|
|
let err = || Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: String::from("Expected 1, 2, or 3 arguments."),
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
let mut args = args.into_iter();
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the first function argument
|
|
|
|
let a = A::from_arg(args.next().ok_or_else(err)?).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 1 was the wrong type. {e}"),
|
|
|
|
})?;
|
|
|
|
// Process the second function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let b = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(b) => Some(B::from_arg(b).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 2 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process the third function argument
|
2022-09-21 00:57:33 +00:00
|
|
|
let c = match args.next() {
|
2023-04-25 10:13:04 +00:00
|
|
|
Some(c) => Some(C::from_arg(c).map_err(|e| Error::InvalidArguments {
|
|
|
|
name: name.to_owned(),
|
|
|
|
message: format!("Argument 3 was the wrong type. {e}"),
|
|
|
|
})?),
|
2022-09-21 00:57:33 +00:00
|
|
|
None => None,
|
|
|
|
};
|
2023-04-25 10:13:04 +00:00
|
|
|
// Process additional function arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
if args.next().is_some() {
|
2023-04-25 10:13:04 +00:00
|
|
|
// Too many arguments
|
2022-09-21 00:57:33 +00:00
|
|
|
return Err(err());
|
|
|
|
}
|
|
|
|
Ok((a, b, c))
|
2022-01-13 17:37:46 +00:00
|
|
|
}
|
|
|
|
}
|