use serde::{Deserialize, Serialize};
use schemars::JsonSchema;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
#[serde(rename_all = "snake_case")]
#[schemars(rename = "functions.expression.Special")]
pub enum Special {
#[schemars(title = "Input")]
Input,
#[schemars(title = "Output")]
Output,
#[schemars(title = "TaskOutputL1Normalized")]
TaskOutputL1Normalized,
#[schemars(title = "TaskOutputWeightedSum")]
TaskOutputWeightedSum,
#[schemars(title = "InputItemsOutputLength")]
InputItemsOutputLength,
#[schemars(title = "InputItemsOptionalContextSplit")]
InputItemsOptionalContextSplit,
#[schemars(title = "InputItemsOptionalContextMerge")]
InputItemsOptionalContextMerge,
}
pub trait FromSpecial: Sized {
fn from_special(
special: &Special,
params: &super::Params,
) -> Result<Self, super::ExpressionError>;
}
macro_rules! impl_from_special_unsupported {
($($ty:ty),+ $(,)?) => {
$(
impl $crate::functions::expression::FromSpecial for $ty {
fn from_special(
_special: &$crate::functions::expression::Special,
_params: &$crate::functions::expression::Params,
) -> Result<Self, $crate::functions::expression::ExpressionError> {
Err($crate::functions::expression::ExpressionError::UnsupportedSpecial)
}
}
)+
};
}
pub(crate) use impl_from_special_unsupported;
impl_from_special_unsupported!(bool, i64, String);
impl<K, V, S> FromSpecial for indexmap::IndexMap<K, V, S>
where
K: Sized,
V: Sized,
S: Sized,
{
fn from_special(
_special: &Special,
_params: &super::Params,
) -> Result<Self, super::ExpressionError> {
Err(super::ExpressionError::UnsupportedSpecial)
}
}
impl FromSpecial for u64 {
fn from_special(
special: &Special,
params: &super::Params,
) -> Result<Self, super::ExpressionError> {
match special {
Special::InputItemsOutputLength => {
let input = match params {
super::Params::Owned(o) => &o.input,
super::Params::Ref(r) => r.input,
};
match input {
super::InputValue::Object(map) => match map.get("items") {
Some(super::InputValue::Array(arr)) => Ok(arr.len() as u64),
_ => Err(super::ExpressionError::UnsupportedSpecial),
},
_ => Err(super::ExpressionError::UnsupportedSpecial),
}
}
_ => Err(super::ExpressionError::UnsupportedSpecial),
}
}
}
impl<T: FromSpecial> FromSpecial for super::OneOrMany<T> {
fn from_special(
special: &Special,
params: &super::Params,
) -> Result<Self, super::ExpressionError> {
Ok(super::OneOrMany::One(T::from_special(special, params)?))
}
}
impl<T: FromSpecial> FromSpecial for Option<T> {
fn from_special(
special: &Special,
params: &super::Params,
) -> Result<Self, super::ExpressionError> {
Ok(Some(T::from_special(special, params)?))
}
}