objectiveai_sdk/functions/expression/
expression.rs1use super::special::FromSpecial;
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize, de::DeserializeOwned};
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
9#[serde(untagged)]
10#[schemars(rename = "functions.expression.OneOrMany.{T}")]
11pub enum OneOrMany<T> {
12 #[schemars(title = "One")]
14 One(T),
15 #[schemars(title = "Many")]
17 Many(Vec<T>),
18}
19
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
36#[serde(deny_unknown_fields)]
37#[schemars(rename = "functions.expression.Expression")]
38pub enum Expression {
39 #[schemars(title = "JMESPath")]
41 #[serde(rename = "$jmespath")]
42 JMESPath(String),
43 #[schemars(title = "Starlark")]
45 #[serde(rename = "$starlark")]
46 Starlark(String),
47 #[schemars(title = "Special")]
49 #[serde(rename = "$special")]
50 Special(super::Special),
51}
52
53impl Expression {
54 pub fn compile_one_or_many<T>(
60 &self,
61 params: &super::Params,
62 ) -> Result<OneOrMany<T>, super::ExpressionError>
63 where
64 T: DeserializeOwned
65 + super::starlark::FromStarlarkValue
66 + super::special::FromSpecial,
67 {
68 match self {
69 Expression::JMESPath(jmespath) => {
70 let expr = super::JMESPATH_RUNTIME.compile(jmespath)?;
71 let value = expr.search(params)?;
72 let json = serde_json::to_value(value)?;
73 Self::deserialize_result(json)
74 }
75 Expression::Starlark(starlark) => {
76 OneOrMany::<T>::from_starlark(starlark, params)
77 }
78 Expression::Special(special) => {
79 OneOrMany::<T>::from_special(special, params)
80 }
81 }
82 }
83
84 fn deserialize_result<T>(
86 value: serde_json::Value,
87 ) -> Result<OneOrMany<T>, super::ExpressionError>
88 where
89 T: DeserializeOwned,
90 {
91 let value: Option<OneOrMany<Option<T>>> = serde_json::from_value(value)
92 .map_err(super::ExpressionError::DeserializationError)?;
93 Ok(match value {
94 Some(OneOrMany::One(Some(v))) => OneOrMany::One(v),
95 Some(OneOrMany::One(None)) => OneOrMany::Many(Vec::new()),
96 Some(OneOrMany::Many(mut vs)) => {
97 vs.retain(|v| v.is_some());
98 if vs.is_empty() {
99 OneOrMany::Many(Vec::new())
100 } else if vs.len() == 1 {
101 OneOrMany::One(vs.into_iter().flatten().next().unwrap())
102 } else {
103 OneOrMany::Many(vs.into_iter().flatten().collect())
104 }
105 }
106 None => OneOrMany::Many(Vec::new()),
107 })
108 }
109
110 pub fn compile_one<T>(
116 &self,
117 params: &super::Params,
118 ) -> Result<T, super::ExpressionError>
119 where
120 T: DeserializeOwned
121 + super::starlark::FromStarlarkValue
122 + super::special::FromSpecial,
123 {
124 let result = self.compile_one_or_many(params)?;
125 match result {
126 OneOrMany::One(value) => Ok(value),
127 OneOrMany::Many(_) => {
128 Err(super::ExpressionError::ExpectedOneValueFoundMany)
129 }
130 }
131 }
132}
133
134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
157#[serde(untagged)]
158#[schemars(rename = "functions.expression.WithExpression.{T}")]
159pub enum WithExpression<T> {
160 #[schemars(title = "Expression")]
162 Expression(Expression),
163 #[schemars(title = "Value")]
165 Value(T),
166}
167
168impl<T> std::default::Default for WithExpression<T>
169where
170 T: Default,
171{
172 fn default() -> Self {
173 WithExpression::Value(T::default())
174 }
175}
176
177impl<T> WithExpression<T>
178where
179 T: DeserializeOwned
180 + super::starlark::FromStarlarkValue
181 + super::special::FromSpecial,
182{
183 pub fn compile_one_or_many(
188 self,
189 params: &super::Params,
190 ) -> Result<OneOrMany<T>, super::ExpressionError> {
191 match self {
192 WithExpression::Expression(expr) => {
193 expr.compile_one_or_many(params)
194 }
195 WithExpression::Value(value) => Ok(OneOrMany::One(value)),
196 }
197 }
198
199 pub fn compile_one(
204 self,
205 params: &super::Params,
206 ) -> Result<T, super::ExpressionError> {
207 match self {
208 WithExpression::Expression(expr) => expr.compile_one(params),
209 WithExpression::Value(value) => Ok(value),
210 }
211 }
212}
213
214impl<T: super::starlark::FromStarlarkValue> super::starlark::FromStarlarkValue
215 for WithExpression<T>
216{
217 fn from_starlark_value(
218 value: &starlark::values::Value,
219 ) -> Result<Self, super::ExpressionError> {
220 T::from_starlark_value(value).map(WithExpression::Value)
221 }
222}
223
224impl<T: super::special::FromSpecial> FromSpecial
225 for super::expression::WithExpression<T>
226{
227 fn from_special(
228 special: &super::special::Special,
229 params: &super::Params,
230 ) -> Result<Self, super::ExpressionError> {
231 Ok(super::expression::WithExpression::Value(T::from_special(
232 special, params,
233 )?))
234 }
235}
236
237impl<T> WithExpression<Option<T>> {
238 pub fn is_none(&self) -> bool {
239 matches!(self, WithExpression::Value(None))
240 }
241}
242