use crate::executor::expression::{ExpressionError, ExpressionErrorType};
use linkrs_core::Value;
#[allow(improper_ctypes_definitions)]
pub type UdfCreateFn = unsafe extern "C" fn() -> *mut dyn UdfPlugin;
#[allow(improper_ctypes_definitions)]
pub type UdfDestroyFn = unsafe extern "C" fn(*mut dyn UdfPlugin);
pub type UdfAbiVersionFn = unsafe extern "C" fn() -> u32;
pub const UDF_CREATE_SYMBOL: &str = "udf_create";
pub const UDF_DESTROY_SYMBOL: &str = "udf_destroy";
pub const UDF_ABI_VERSION_SYMBOL: &str = "udf_abi_version";
pub const UDF_ABI_VERSION: u32 = 1;
pub trait UdfPlugin: Send + Sync {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn min_arity(&self) -> usize;
fn max_arity(&self) -> usize;
fn is_pure(&self) -> bool;
fn execute(&self, args: &[Value]) -> Result<Value, ExpressionError>;
}
pub type SharedPlugin = std::sync::Arc<dyn UdfPlugin>;
pub fn check_arity(plugin: &dyn UdfPlugin, args: &[Value]) -> Result<(), ExpressionError> {
if args.len() < plugin.min_arity() || args.len() > plugin.max_arity() {
return Err(ExpressionError::new(
ExpressionErrorType::InvalidArgumentCount,
format!(
"function '{}' expects {}..={} argument(s), got {}",
plugin.name(),
plugin.min_arity(),
plugin.max_arity(),
args.len(),
),
));
}
Ok(())
}