1#![allow(unused)]
26
27use serde_json::ser;
28
29#[derive(serde::Deserialize, serde::Serialize, Debug)]
30pub struct Config<'a> {
31 pub name: &'a str,
32 pub title: &'a str,
33 pub description: &'a str,
34 #[serde(default)]
35 pub role: Role,
36 #[serde(default)]
37 pub eligibility: Eligibility,
38}
39
40impl<'a> Config<'a> {
41 #[must_use]
42 pub fn action(name: &'a str, title: &'a str, description: &'a str) -> Self {
43 Self {
44 name,
45 title,
46 description,
47 role: Role::Action,
48 eligibility: Eligibility::default(),
49 }
50 }
51
52 #[must_use]
53 pub fn with_eligibility(mut self, eligibility: Eligibility) -> Self {
54 self.eligibility = eligibility;
55 self
56 }
57}
58
59impl std::fmt::Display for Config<'_> {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 let s = serde_json::to_string(self).expect("Failed to serialize config to JSON");
67 write!(f, "{s}")
68 }
69}
70
71#[derive(serde::Deserialize, serde::Serialize, Debug)]
72#[serde(rename_all = "lowercase")]
73#[derive(Default)]
74pub enum Role {
75 #[default]
76 Action,
77 Selector,
78 Subflow,
79 Task,
80}
81
82#[derive(serde::Deserialize, serde::Serialize, Debug)]
83#[serde(rename_all = "camelCase")]
84pub struct Eligibility {
85 #[serde(skip_serializing_if = "Option::is_none")]
86 pub auto: Option<Auto>,
87 #[serde(skip_serializing_if = "Option::is_none")]
88 pub run_once: Option<bool>,
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub run_once_per_session: Option<bool>,
91 #[serde(skip_serializing_if = "Option::is_none")]
92 pub continuation: Option<bool>,
93 #[serde(skip_serializing_if = "Vec::is_empty")]
94 pub predicates: Vec<Predicate>,
95 #[serde(skip_serializing_if = "Option::is_none")]
96 pub logical_operator: Option<PredicateLogicalOperator>,
97}
98
99impl Eligibility {
100 #[must_use]
101 pub fn auto() -> Self {
102 Eligibility {
103 auto: Some(Auto::new()),
104 run_once: None,
105 run_once_per_session: None,
106 continuation: None,
107 predicates: vec![],
108 logical_operator: None,
109 }
110 }
111
112 #[must_use]
113 pub fn auto_with_default(value: bool) -> Self {
114 Eligibility {
115 auto: Some(Auto::new().default(value)),
116 run_once: None,
117 run_once_per_session: None,
118 continuation: None,
119 predicates: vec![],
120 logical_operator: None,
121 }
122 }
123
124 #[must_use]
125 pub fn with_predicate<P: Into<Predicate>>(mut self, predicate: P) -> Self {
126 self.predicates = vec![predicate.into()];
127 self
128 }
129
130 #[must_use]
131 pub fn matching_any_predicate(mut self, predicates: &[Predicate]) -> Self {
132 self.predicates = predicates.to_vec();
133 self.logical_operator = Some(PredicateLogicalOperator::Or);
134 self
135 }
136
137 #[must_use]
138 pub fn matching_all_predicates(mut self, predicates: &[Predicate]) -> Self {
139 self.predicates = predicates.to_vec();
140 self.logical_operator = Some(PredicateLogicalOperator::And);
141 self
142 }
143}
144
145impl Default for Eligibility {
146 fn default() -> Self {
147 Self::auto()
148 }
149}
150
151#[derive(serde::Deserialize, serde::Serialize, Debug, Default)]
152pub struct Auto {
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub default: Option<bool>,
155}
156
157impl Auto {
158 #[must_use]
159 pub fn new() -> Self {
160 Self { default: None }
161 }
162
163 #[must_use]
164 pub fn default(mut self, value: bool) -> Self {
165 self.default = Some(value);
166 self
167 }
168}
169
170#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
171pub struct Predicate {
172 #[serde(flatten)]
173 pub predicate_type: PredicateType,
174 pub operator: Operator,
175 pub value: serde_json::Value,
176}
177
178impl Predicate {
179 pub fn setting<I: ToString>(
180 identifier: &I,
181 operator: Operator,
182 value: impl serde::Serialize,
183 ) -> Self {
184 Self {
185 predicate_type: PredicateType::Setting {
186 identifier: identifier.to_string(),
187 },
188 operator,
189 value: serde_json::json!(value),
190 }
191 }
192}
193
194pub enum ViewType<'a> {
195 In(&'a [&'a str]),
196 NotIn(&'a [&'a str]),
197}
198
199impl From<ViewType<'_>> for Predicate {
200 fn from(predicate: ViewType) -> Self {
201 match predicate {
202 ViewType::In(value) => Predicate {
203 predicate_type: PredicateType::ViewType,
204 operator: Operator::In,
205 value: serde_json::json!(value),
206 },
207 ViewType::NotIn(value) => Predicate {
208 predicate_type: PredicateType::ViewType,
209 operator: Operator::NotIn,
210 value: serde_json::json!(value),
211 },
212 }
213 }
214}
215
216pub struct Setting {
217 identifier: String,
218 operator: Operator,
219 value: serde_json::Value,
220}
221
222impl Setting {
223 pub fn new(
224 identifier: &impl ToString,
225 operator: Operator,
226 value: impl serde::Serialize,
227 ) -> Self {
228 Self {
229 identifier: identifier.to_string(),
230 operator,
231 value: serde_json::json!(value),
232 }
233 }
234
235 pub fn eq(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
236 Self::new(identifier, Operator::Eq, value)
237 }
238
239 pub fn ne(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
240 Self::new(identifier, Operator::Ne, value)
241 }
242
243 pub fn lt(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
244 Self::new(identifier, Operator::Lt, value)
245 }
246
247 pub fn lte(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
248 Self::new(identifier, Operator::Lte, value)
249 }
250
251 pub fn gt(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
252 Self::new(identifier, Operator::Gt, value)
253 }
254
255 pub fn gte(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
256 Self::new(identifier, Operator::Gte, value)
257 }
258
259 pub fn in_(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
260 Self::new(identifier, Operator::In, value)
261 }
262
263 pub fn not_in(identifier: &impl ToString, value: impl serde::Serialize) -> Self {
264 Self::new(identifier, Operator::NotIn, value)
265 }
266}
267
268impl From<Setting> for Predicate {
269 fn from(setting: Setting) -> Self {
270 Predicate {
271 predicate_type: PredicateType::Setting {
272 identifier: setting.identifier,
273 },
274 operator: setting.operator,
275 value: setting.value,
276 }
277 }
278}
279
280#[derive(serde::Deserialize, serde::Serialize, Debug, Clone)]
281#[serde(rename_all = "camelCase", tag = "type")]
282pub enum PredicateType {
283 Setting { identifier: String },
284 ViewType,
285}
286
287#[derive(serde::Deserialize, serde::Serialize, Debug, Copy, Clone)]
288pub enum Operator {
289 #[serde(rename = "==")]
290 Eq,
291 #[serde(rename = "!=")]
292 Ne,
293 #[serde(rename = "<")]
294 Lt,
295 #[serde(rename = "<=")]
296 Lte,
297 #[serde(rename = ">")]
298 Gt,
299 #[serde(rename = ">=")]
300 Gte,
301 #[serde(rename = "in")]
302 In,
303 #[serde(rename = "not in")]
304 NotIn,
305}
306
307#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy)]
308#[serde(rename_all = "lowercase")]
309pub enum PredicateLogicalOperator {
310 And,
311 Or,
312}