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(
36 Debug,
37 Clone,
38 PartialEq,
39 Serialize,
40 Deserialize,
41 JsonSchema,
42 arbitrary::Arbitrary,
43)]
44#[serde(deny_unknown_fields)]
45#[schemars(rename = "functions.expression.Expression")]
46pub enum Expression {
47 #[schemars(title = "JMESPath")]
49 #[serde(rename = "$jmespath")]
50 JMESPath(String),
51 #[schemars(title = "Starlark")]
53 #[serde(rename = "$starlark")]
54 Starlark(String),
55 #[schemars(title = "Special")]
57 #[serde(rename = "$special")]
58 Special(super::Special),
59}
60
61impl Expression {
62 pub fn compile_one_or_many<T>(
68 &self,
69 params: &super::Params,
70 ) -> Result<OneOrMany<T>, super::ExpressionError>
71 where
72 T: DeserializeOwned
73 + super::starlark::FromStarlarkValue
74 + super::special::FromSpecial,
75 {
76 match self {
77 Expression::JMESPath(jmespath) => {
78 let expr = super::JMESPATH_RUNTIME.compile(jmespath)?;
79 let value = expr.search(params)?;
80 let json = serde_json::to_value(value)?;
81 Self::deserialize_result(json)
82 }
83 Expression::Starlark(starlark) => {
84 OneOrMany::<T>::from_starlark(starlark, params)
85 }
86 Expression::Special(special) => {
87 OneOrMany::<T>::from_special(special, params)
88 }
89 }
90 }
91
92 fn deserialize_result<T>(
94 value: serde_json::Value,
95 ) -> Result<OneOrMany<T>, super::ExpressionError>
96 where
97 T: DeserializeOwned,
98 {
99 let value: Option<OneOrMany<Option<T>>> = serde_json::from_value(value)
100 .map_err(super::ExpressionError::DeserializationError)?;
101 Ok(match value {
102 Some(OneOrMany::One(Some(v))) => OneOrMany::One(v),
103 Some(OneOrMany::One(None)) => OneOrMany::Many(Vec::new()),
104 Some(OneOrMany::Many(mut vs)) => {
105 vs.retain(|v| v.is_some());
106 if vs.is_empty() {
107 OneOrMany::Many(Vec::new())
108 } else if vs.len() == 1 {
109 OneOrMany::One(vs.into_iter().flatten().next().unwrap())
110 } else {
111 OneOrMany::Many(vs.into_iter().flatten().collect())
112 }
113 }
114 None => OneOrMany::Many(Vec::new()),
115 })
116 }
117
118 pub fn compile_one<T>(
124 &self,
125 params: &super::Params,
126 ) -> Result<T, super::ExpressionError>
127 where
128 T: DeserializeOwned
129 + super::starlark::FromStarlarkValue
130 + super::special::FromSpecial,
131 {
132 let result = self.compile_one_or_many(params)?;
133 match result {
134 OneOrMany::One(value) => Ok(value),
135 OneOrMany::Many(_) => {
136 Err(super::ExpressionError::ExpectedOneValueFoundMany)
137 }
138 }
139 }
140}
141
142#[derive(
165 Debug,
166 Clone,
167 PartialEq,
168 Serialize,
169 Deserialize,
170 JsonSchema,
171 arbitrary::Arbitrary,
172)]
173#[serde(untagged)]
174#[schemars(rename = "functions.expression.WithExpression.{T}")]
175pub enum WithExpression<T> {
176 #[schemars(title = "Expression")]
178 Expression(Expression),
179 #[schemars(title = "Value")]
181 Value(T),
182}
183
184impl<T> std::default::Default for WithExpression<T>
185where
186 T: Default,
187{
188 fn default() -> Self {
189 WithExpression::Value(T::default())
190 }
191}
192
193impl<T> WithExpression<T>
194where
195 T: DeserializeOwned
196 + super::starlark::FromStarlarkValue
197 + super::special::FromSpecial,
198{
199 pub fn compile_one_or_many(
204 self,
205 params: &super::Params,
206 ) -> Result<OneOrMany<T>, super::ExpressionError> {
207 match self {
208 WithExpression::Expression(expr) => {
209 expr.compile_one_or_many(params)
210 }
211 WithExpression::Value(value) => Ok(OneOrMany::One(value)),
212 }
213 }
214
215 pub fn compile_one(
220 self,
221 params: &super::Params,
222 ) -> Result<T, super::ExpressionError> {
223 match self {
224 WithExpression::Expression(expr) => expr.compile_one(params),
225 WithExpression::Value(value) => Ok(value),
226 }
227 }
228}
229
230impl<T: super::starlark::FromStarlarkValue> super::starlark::FromStarlarkValue
231 for WithExpression<T>
232{
233 fn from_starlark_value(
234 value: &starlark::values::Value,
235 ) -> Result<Self, super::ExpressionError> {
236 T::from_starlark_value(value).map(WithExpression::Value)
237 }
238}
239
240impl<T: super::special::FromSpecial> FromSpecial
241 for super::expression::WithExpression<T>
242{
243 fn from_special(
244 special: &super::special::Special,
245 params: &super::Params,
246 ) -> Result<Self, super::ExpressionError> {
247 Ok(super::expression::WithExpression::Value(T::from_special(
248 special, params,
249 )?))
250 }
251}
252
253impl<T> WithExpression<Option<T>> {
254 pub fn is_none(&self) -> bool {
255 matches!(self, WithExpression::Value(None))
256 }
257}