1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
4#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
5pub enum OperatorType {
6 String,
7 Numeric,
8 Date,
9 Boolean,
10 Binary,
11 IpAddress,
12 Arn,
13 Null,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash, PartialOrd, Ord)]
18#[serde(rename_all = "PascalCase")]
19#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
20pub enum IAMOperator {
21 #[serde(rename = "StringEquals")]
23 StringEquals,
24 #[serde(rename = "StringNotEquals")]
25 StringNotEquals,
26 #[serde(rename = "StringEqualsIgnoreCase")]
27 StringEqualsIgnoreCase,
28 #[serde(rename = "StringNotEqualsIgnoreCase")]
29 StringNotEqualsIgnoreCase,
30 #[serde(rename = "StringLike")]
31 StringLike,
32 #[serde(rename = "StringNotLike")]
33 StringNotLike,
34
35 #[serde(rename = "ForAllValues:StringEquals")]
37 ForAllValuesStringEquals,
38 #[serde(rename = "ForAllValues:StringEqualsIgnoreCase")]
39 ForAllValuesStringEqualsIgnoreCase,
40 #[serde(rename = "ForAnyValue:StringEquals")]
41 ForAnyValueStringEquals,
42 #[serde(rename = "ForAnyValue:StringEqualsIgnoreCase")]
43 ForAnyValueStringEqualsIgnoreCase,
44 #[serde(rename = "ForAllValues:StringNotEquals")]
45 ForAllValuesStringNotEquals,
46 #[serde(rename = "ForAllValues:StringNotEqualsIgnoreCase")]
47 ForAllValuesStringNotEqualsIgnoreCase,
48 #[serde(rename = "ForAnyValue:StringNotEquals")]
49 ForAnyValueStringNotEquals,
50 #[serde(rename = "ForAnyValue:StringNotEqualsIgnoreCase")]
51 ForAnyValueStringNotEqualsIgnoreCase,
52 #[serde(rename = "ForAllValues:StringLike")]
53 ForAllValuesStringLike,
54 #[serde(rename = "ForAnyValue:StringLike")]
55 ForAnyValueStringLike,
56 #[serde(rename = "ForAllValues:StringNotLike")]
57 ForAllValuesStringNotLike,
58 #[serde(rename = "ForAnyValue:StringNotLike")]
59 ForAnyValueStringNotLike,
60
61 #[serde(rename = "NumericEquals")]
63 NumericEquals,
64 #[serde(rename = "NumericNotEquals")]
65 NumericNotEquals,
66 #[serde(rename = "NumericLessThan")]
67 NumericLessThan,
68 #[serde(rename = "NumericLessThanEquals")]
69 NumericLessThanEquals,
70 #[serde(rename = "NumericGreaterThan")]
71 NumericGreaterThan,
72 #[serde(rename = "NumericGreaterThanEquals")]
73 NumericGreaterThanEquals,
74
75 #[serde(rename = "DateEquals")]
77 DateEquals,
78 #[serde(rename = "DateNotEquals")]
79 DateNotEquals,
80 #[serde(rename = "DateLessThan")]
81 DateLessThan,
82 #[serde(rename = "DateLessThanEquals")]
83 DateLessThanEquals,
84 #[serde(rename = "DateGreaterThan")]
85 DateGreaterThan,
86 #[serde(rename = "DateGreaterThanEquals")]
87 DateGreaterThanEquals,
88
89 #[serde(rename = "Bool")]
91 Bool,
92 #[serde(rename = "ForAllValues:Bool")]
93 ForAllValuesBool,
94 #[serde(rename = "ForAnyValue:Bool")]
95 ForAnyValueBool,
96
97 #[serde(rename = "BinaryEquals")]
99 BinaryEquals,
100
101 #[serde(rename = "IpAddress")]
103 IpAddress,
104 #[serde(rename = "NotIpAddress")]
105 NotIpAddress,
106
107 #[serde(rename = "ArnEquals")]
109 ArnEquals,
110 #[serde(rename = "ArnLike")]
111 ArnLike,
112 #[serde(rename = "ArnNotEquals")]
113 ArnNotEquals,
114 #[serde(rename = "ArnNotLike")]
115 ArnNotLike,
116
117 #[serde(rename = "ForAllValues:ArnEquals")]
119 ForAllValuesArnEquals,
120 #[serde(rename = "ForAllValues:ArnLike")]
121 ForAllValuesArnLike,
122 #[serde(rename = "ForAnyValue:ArnEquals")]
123 ForAnyValueArnEquals,
124 #[serde(rename = "ForAnyValue:ArnLike")]
125 ForAnyValueArnLike,
126 #[serde(rename = "ForAllValues:ArnNotEquals")]
127 ForAllValuesArnNotEquals,
128 #[serde(rename = "ForAllValues:ArnNotLike")]
129 ForAllValuesArnNotLike,
130 #[serde(rename = "ForAnyValue:ArnNotEquals")]
131 ForAnyValueArnNotEquals,
132 #[serde(rename = "ForAnyValue:ArnNotLike")]
133 ForAnyValueArnNotLike,
134
135 #[serde(rename = "Null")]
137 Null,
138
139 #[serde(rename = "StringEqualsIfExists")]
141 StringEqualsIfExists,
142 #[serde(rename = "StringNotEqualsIfExists")]
143 StringNotEqualsIfExists,
144 #[serde(rename = "StringEqualsIgnoreCaseIfExists")]
145 StringEqualsIgnoreCaseIfExists,
146 #[serde(rename = "StringNotEqualsIgnoreCaseIfExists")]
147 StringNotEqualsIgnoreCaseIfExists,
148 #[serde(rename = "StringLikeIfExists")]
149 StringLikeIfExists,
150 #[serde(rename = "StringNotLikeIfExists")]
151 StringNotLikeIfExists,
152 #[serde(rename = "NumericEqualsIfExists")]
153 NumericEqualsIfExists,
154 #[serde(rename = "NumericNotEqualsIfExists")]
155 NumericNotEqualsIfExists,
156 #[serde(rename = "NumericLessThanIfExists")]
157 NumericLessThanIfExists,
158 #[serde(rename = "NumericLessThanEqualsIfExists")]
159 NumericLessThanEqualsIfExists,
160 #[serde(rename = "NumericGreaterThanIfExists")]
161 NumericGreaterThanIfExists,
162 #[serde(rename = "NumericGreaterThanEqualsIfExists")]
163 NumericGreaterThanEqualsIfExists,
164 #[serde(rename = "DateEqualsIfExists")]
165 DateEqualsIfExists,
166 #[serde(rename = "DateNotEqualsIfExists")]
167 DateNotEqualsIfExists,
168 #[serde(rename = "DateLessThanIfExists")]
169 DateLessThanIfExists,
170 #[serde(rename = "DateLessThanEqualsIfExists")]
171 DateLessThanEqualsIfExists,
172 #[serde(rename = "DateGreaterThanIfExists")]
173 DateGreaterThanIfExists,
174 #[serde(rename = "DateGreaterThanEqualsIfExists")]
175 DateGreaterThanEqualsIfExists,
176 #[serde(rename = "BoolIfExists")]
177 BoolIfExists,
178 #[serde(rename = "BinaryEqualsIfExists")]
179 BinaryEqualsIfExists,
180 #[serde(rename = "IpAddressIfExists")]
181 IpAddressIfExists,
182 #[serde(rename = "NotIpAddressIfExists")]
183 NotIpAddressIfExists,
184 #[serde(rename = "ArnEqualsIfExists")]
185 ArnEqualsIfExists,
186 #[serde(rename = "ArnLikeIfExists")]
187 ArnLikeIfExists,
188 #[serde(rename = "ArnNotEqualsIfExists")]
189 ArnNotEqualsIfExists,
190 #[serde(rename = "ArnNotLikeIfExists")]
191 ArnNotLikeIfExists,
192}
193
194impl IAMOperator {
195 #[must_use]
197 pub fn is_string_operator(&self) -> bool {
198 matches!(
199 self,
200 IAMOperator::StringEquals
201 | IAMOperator::StringNotEquals
202 | IAMOperator::StringEqualsIgnoreCase
203 | IAMOperator::StringNotEqualsIgnoreCase
204 | IAMOperator::StringLike
205 | IAMOperator::StringNotLike
206 | IAMOperator::ForAllValuesStringEquals
207 | IAMOperator::ForAllValuesStringEqualsIgnoreCase
208 | IAMOperator::ForAnyValueStringEquals
209 | IAMOperator::ForAnyValueStringEqualsIgnoreCase
210 | IAMOperator::ForAllValuesStringNotEquals
211 | IAMOperator::ForAllValuesStringNotEqualsIgnoreCase
212 | IAMOperator::ForAnyValueStringNotEquals
213 | IAMOperator::ForAnyValueStringNotEqualsIgnoreCase
214 | IAMOperator::ForAllValuesStringLike
215 | IAMOperator::ForAnyValueStringLike
216 | IAMOperator::ForAllValuesStringNotLike
217 | IAMOperator::ForAnyValueStringNotLike
218 | IAMOperator::StringEqualsIfExists
219 | IAMOperator::StringNotEqualsIfExists
220 | IAMOperator::StringEqualsIgnoreCaseIfExists
221 | IAMOperator::StringNotEqualsIgnoreCaseIfExists
222 | IAMOperator::StringLikeIfExists
223 | IAMOperator::StringNotLikeIfExists
224 )
225 }
226
227 #[must_use]
229 pub fn is_numeric_operator(&self) -> bool {
230 matches!(
231 self,
232 IAMOperator::NumericEquals
233 | IAMOperator::NumericNotEquals
234 | IAMOperator::NumericLessThan
235 | IAMOperator::NumericLessThanEquals
236 | IAMOperator::NumericGreaterThan
237 | IAMOperator::NumericGreaterThanEquals
238 | IAMOperator::NumericEqualsIfExists
239 | IAMOperator::NumericNotEqualsIfExists
240 | IAMOperator::NumericLessThanIfExists
241 | IAMOperator::NumericLessThanEqualsIfExists
242 | IAMOperator::NumericGreaterThanIfExists
243 | IAMOperator::NumericGreaterThanEqualsIfExists
244 )
245 }
246
247 #[must_use]
249 pub fn is_date_operator(&self) -> bool {
250 matches!(
251 self,
252 IAMOperator::DateEquals
253 | IAMOperator::DateNotEquals
254 | IAMOperator::DateLessThan
255 | IAMOperator::DateLessThanEquals
256 | IAMOperator::DateGreaterThan
257 | IAMOperator::DateGreaterThanEquals
258 | IAMOperator::DateEqualsIfExists
259 | IAMOperator::DateNotEqualsIfExists
260 | IAMOperator::DateLessThanIfExists
261 | IAMOperator::DateLessThanEqualsIfExists
262 | IAMOperator::DateGreaterThanIfExists
263 | IAMOperator::DateGreaterThanEqualsIfExists
264 )
265 }
266
267 #[must_use]
269 pub fn is_boolean_operator(&self) -> bool {
270 matches!(
271 self,
272 IAMOperator::Bool
273 | IAMOperator::ForAllValuesBool
274 | IAMOperator::ForAnyValueBool
275 | IAMOperator::BoolIfExists
276 )
277 }
278
279 #[must_use]
281 pub fn is_arn_operator(&self) -> bool {
282 matches!(
283 self,
284 IAMOperator::ArnEquals
285 | IAMOperator::ArnLike
286 | IAMOperator::ArnNotEquals
287 | IAMOperator::ArnNotLike
288 | IAMOperator::ForAllValuesArnEquals
289 | IAMOperator::ForAllValuesArnLike
290 | IAMOperator::ForAnyValueArnEquals
291 | IAMOperator::ForAnyValueArnLike
292 | IAMOperator::ForAllValuesArnNotEquals
293 | IAMOperator::ForAllValuesArnNotLike
294 | IAMOperator::ForAnyValueArnNotEquals
295 | IAMOperator::ForAnyValueArnNotLike
296 | IAMOperator::ArnEqualsIfExists
297 | IAMOperator::ArnLikeIfExists
298 | IAMOperator::ArnNotEqualsIfExists
299 | IAMOperator::ArnNotLikeIfExists
300 )
301 }
302
303 #[must_use]
305 pub fn is_ip_operator(&self) -> bool {
306 matches!(
307 self,
308 IAMOperator::IpAddress
309 | IAMOperator::NotIpAddress
310 | IAMOperator::IpAddressIfExists
311 | IAMOperator::NotIpAddressIfExists
312 )
313 }
314
315 #[must_use]
317 pub fn is_binary_operator(&self) -> bool {
318 matches!(
319 self,
320 IAMOperator::BinaryEquals | IAMOperator::BinaryEqualsIfExists
321 )
322 }
323
324 #[must_use]
326 pub fn supports_wildcards(&self) -> bool {
327 matches!(
328 self,
329 IAMOperator::StringLike
330 | IAMOperator::StringNotLike
331 | IAMOperator::ForAllValuesStringLike
332 | IAMOperator::ForAnyValueStringLike
333 | IAMOperator::ForAllValuesStringNotLike
334 | IAMOperator::ForAnyValueStringNotLike
335 | IAMOperator::StringLikeIfExists
336 | IAMOperator::StringNotLikeIfExists
337 | IAMOperator::ArnEquals
338 | IAMOperator::ArnLike
339 | IAMOperator::ArnNotEquals
340 | IAMOperator::ArnNotLike
341 | IAMOperator::ForAllValuesArnEquals
342 | IAMOperator::ForAllValuesArnLike
343 | IAMOperator::ForAnyValueArnEquals
344 | IAMOperator::ForAnyValueArnLike
345 | IAMOperator::ForAllValuesArnNotEquals
346 | IAMOperator::ForAllValuesArnNotLike
347 | IAMOperator::ForAnyValueArnNotEquals
348 | IAMOperator::ForAnyValueArnNotLike
349 | IAMOperator::ArnEqualsIfExists
350 | IAMOperator::ArnLikeIfExists
351 | IAMOperator::ArnNotEqualsIfExists
352 | IAMOperator::ArnNotLikeIfExists
353 )
354 }
355
356 #[must_use]
358 pub fn supports_policy_variables(&self) -> bool {
359 !self.is_numeric_operator()
360 && !self.is_date_operator()
361 && !self.is_binary_operator()
362 && !self.is_ip_operator()
363 }
364
365 #[must_use]
367 pub fn is_multivalued_operator(&self) -> bool {
368 self.to_string().starts_with("ForAllValues:")
369 || self.to_string().starts_with("ForAnyValue:")
370 }
371
372 #[must_use]
374 pub fn is_if_exists_operator(&self) -> bool {
375 self.to_string().ends_with("IfExists")
376 }
377
378 #[must_use]
380 pub fn is_negated_operator(&self) -> bool {
381 matches!(
382 self,
383 IAMOperator::StringNotEquals
384 | IAMOperator::StringNotEqualsIgnoreCase
385 | IAMOperator::StringNotLike
386 | IAMOperator::ForAllValuesStringNotEquals
387 | IAMOperator::ForAllValuesStringNotEqualsIgnoreCase
388 | IAMOperator::ForAnyValueStringNotEquals
389 | IAMOperator::ForAnyValueStringNotEqualsIgnoreCase
390 | IAMOperator::ForAllValuesStringNotLike
391 | IAMOperator::ForAnyValueStringNotLike
392 | IAMOperator::NumericNotEquals
393 | IAMOperator::DateNotEquals
394 | IAMOperator::NotIpAddress
395 | IAMOperator::ArnNotEquals
396 | IAMOperator::ArnNotLike
397 | IAMOperator::ForAllValuesArnNotEquals
398 | IAMOperator::ForAllValuesArnNotLike
399 | IAMOperator::ForAnyValueArnNotEquals
400 | IAMOperator::ForAnyValueArnNotLike
401 | IAMOperator::StringNotEqualsIfExists
402 | IAMOperator::StringNotEqualsIgnoreCaseIfExists
403 | IAMOperator::StringNotLikeIfExists
404 | IAMOperator::NumericNotEqualsIfExists
405 | IAMOperator::DateNotEqualsIfExists
406 | IAMOperator::NotIpAddressIfExists
407 | IAMOperator::ArnNotEqualsIfExists
408 | IAMOperator::ArnNotLikeIfExists
409 )
410 }
411
412 #[must_use]
415 pub fn supports_multiple_values(&self) -> bool {
416 !matches!(
418 self,
419 IAMOperator::Null | IAMOperator::Bool | IAMOperator::BoolIfExists
420 )
421 }
422
423 #[must_use]
430 pub fn category(&self) -> OperatorType {
431 if self.is_string_operator() {
432 OperatorType::String
433 } else if self.is_numeric_operator() {
434 OperatorType::Numeric
435 } else if self.is_date_operator() {
436 OperatorType::Date
437 } else if self.is_boolean_operator() {
438 OperatorType::Boolean
439 } else if self.is_binary_operator() {
440 OperatorType::Binary
441 } else if self.is_ip_operator() {
442 OperatorType::IpAddress
443 } else if self.is_arn_operator() {
444 OperatorType::Arn
445 } else if matches!(self, IAMOperator::Null) {
446 OperatorType::Null
447 } else {
448 panic!("Unknown operator category for operator: {}", self.as_str())
449 }
450 }
451
452 #[must_use]
454 pub fn as_str(&self) -> &'static str {
455 match self {
456 IAMOperator::StringEquals => "StringEquals",
457 IAMOperator::StringNotEquals => "StringNotEquals",
458 IAMOperator::StringEqualsIgnoreCase => "StringEqualsIgnoreCase",
459 IAMOperator::StringNotEqualsIgnoreCase => "StringNotEqualsIgnoreCase",
460 IAMOperator::StringLike => "StringLike",
461 IAMOperator::StringNotLike => "StringNotLike",
462 IAMOperator::ForAllValuesStringEquals => "ForAllValues:StringEquals",
463 IAMOperator::ForAllValuesStringEqualsIgnoreCase => {
464 "ForAllValues:StringEqualsIgnoreCase"
465 }
466 IAMOperator::ForAnyValueStringEquals => "ForAnyValue:StringEquals",
467 IAMOperator::ForAnyValueStringEqualsIgnoreCase => "ForAnyValue:StringEqualsIgnoreCase",
468 IAMOperator::ForAllValuesStringNotEquals => "ForAllValues:StringNotEquals",
469 IAMOperator::ForAllValuesStringNotEqualsIgnoreCase => {
470 "ForAllValues:StringNotEqualsIgnoreCase"
471 }
472 IAMOperator::ForAnyValueStringNotEquals => "ForAnyValue:StringNotEquals",
473 IAMOperator::ForAnyValueStringNotEqualsIgnoreCase => {
474 "ForAnyValue:StringNotEqualsIgnoreCase"
475 }
476 IAMOperator::ForAllValuesStringLike => "ForAllValues:StringLike",
477 IAMOperator::ForAnyValueStringLike => "ForAnyValue:StringLike",
478 IAMOperator::ForAllValuesStringNotLike => "ForAllValues:StringNotLike",
479 IAMOperator::ForAnyValueStringNotLike => "ForAnyValue:StringNotLike",
480 IAMOperator::NumericEquals => "NumericEquals",
481 IAMOperator::NumericNotEquals => "NumericNotEquals",
482 IAMOperator::NumericLessThan => "NumericLessThan",
483 IAMOperator::NumericLessThanEquals => "NumericLessThanEquals",
484 IAMOperator::NumericGreaterThan => "NumericGreaterThan",
485 IAMOperator::NumericGreaterThanEquals => "NumericGreaterThanEquals",
486 IAMOperator::DateEquals => "DateEquals",
487 IAMOperator::DateNotEquals => "DateNotEquals",
488 IAMOperator::DateLessThan => "DateLessThan",
489 IAMOperator::DateLessThanEquals => "DateLessThanEquals",
490 IAMOperator::DateGreaterThan => "DateGreaterThan",
491 IAMOperator::DateGreaterThanEquals => "DateGreaterThanEquals",
492 IAMOperator::Bool => "Bool",
493 IAMOperator::ForAllValuesBool => "ForAllValues:Bool",
494 IAMOperator::ForAnyValueBool => "ForAnyValue:Bool",
495 IAMOperator::BinaryEquals => "BinaryEquals",
496 IAMOperator::IpAddress => "IpAddress",
497 IAMOperator::NotIpAddress => "NotIpAddress",
498 IAMOperator::ArnEquals => "ArnEquals",
499 IAMOperator::ArnLike => "ArnLike",
500 IAMOperator::ArnNotEquals => "ArnNotEquals",
501 IAMOperator::ArnNotLike => "ArnNotLike",
502 IAMOperator::ForAllValuesArnEquals => "ForAllValues:ArnEquals",
503 IAMOperator::ForAllValuesArnLike => "ForAllValues:ArnLike",
504 IAMOperator::ForAnyValueArnEquals => "ForAnyValue:ArnEquals",
505 IAMOperator::ForAnyValueArnLike => "ForAnyValue:ArnLike",
506 IAMOperator::ForAllValuesArnNotEquals => "ForAllValues:ArnNotEquals",
507 IAMOperator::ForAllValuesArnNotLike => "ForAllValues:ArnNotLike",
508 IAMOperator::ForAnyValueArnNotEquals => "ForAnyValue:ArnNotEquals",
509 IAMOperator::ForAnyValueArnNotLike => "ForAnyValue:ArnNotLike",
510 IAMOperator::Null => "Null",
511 IAMOperator::StringEqualsIfExists => "StringEqualsIfExists",
512 IAMOperator::StringNotEqualsIfExists => "StringNotEqualsIfExists",
513 IAMOperator::StringEqualsIgnoreCaseIfExists => "StringEqualsIgnoreCaseIfExists",
514 IAMOperator::StringNotEqualsIgnoreCaseIfExists => "StringNotEqualsIgnoreCaseIfExists",
515 IAMOperator::StringLikeIfExists => "StringLikeIfExists",
516 IAMOperator::StringNotLikeIfExists => "StringNotLikeIfExists",
517 IAMOperator::NumericEqualsIfExists => "NumericEqualsIfExists",
518 IAMOperator::NumericNotEqualsIfExists => "NumericNotEqualsIfExists",
519 IAMOperator::NumericLessThanIfExists => "NumericLessThanIfExists",
520 IAMOperator::NumericLessThanEqualsIfExists => "NumericLessThanEqualsIfExists",
521 IAMOperator::NumericGreaterThanIfExists => "NumericGreaterThanIfExists",
522 IAMOperator::NumericGreaterThanEqualsIfExists => "NumericGreaterThanEqualsIfExists",
523 IAMOperator::DateEqualsIfExists => "DateEqualsIfExists",
524 IAMOperator::DateNotEqualsIfExists => "DateNotEqualsIfExists",
525 IAMOperator::DateLessThanIfExists => "DateLessThanIfExists",
526 IAMOperator::DateLessThanEqualsIfExists => "DateLessThanEqualsIfExists",
527 IAMOperator::DateGreaterThanIfExists => "DateGreaterThanIfExists",
528 IAMOperator::DateGreaterThanEqualsIfExists => "DateGreaterThanEqualsIfExists",
529 IAMOperator::BoolIfExists => "BoolIfExists",
530 IAMOperator::BinaryEqualsIfExists => "BinaryEqualsIfExists",
531 IAMOperator::IpAddressIfExists => "IpAddressIfExists",
532 IAMOperator::NotIpAddressIfExists => "NotIpAddressIfExists",
533 IAMOperator::ArnEqualsIfExists => "ArnEqualsIfExists",
534 IAMOperator::ArnLikeIfExists => "ArnLikeIfExists",
535 IAMOperator::ArnNotEqualsIfExists => "ArnNotEqualsIfExists",
536 IAMOperator::ArnNotLikeIfExists => "ArnNotLikeIfExists",
537 }
538 }
539}
540
541impl std::fmt::Display for IAMOperator {
542 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543 write!(f, "{}", self.as_str())
544 }
545}
546
547impl std::str::FromStr for IAMOperator {
548 type Err = String;
549
550 fn from_str(s: &str) -> Result<Self, Self::Err> {
551 match s {
552 "StringEquals" => Ok(IAMOperator::StringEquals),
553 "StringNotEquals" => Ok(IAMOperator::StringNotEquals),
554 "StringEqualsIgnoreCase" => Ok(IAMOperator::StringEqualsIgnoreCase),
555 "StringNotEqualsIgnoreCase" => Ok(IAMOperator::StringNotEqualsIgnoreCase),
556 "StringLike" => Ok(IAMOperator::StringLike),
557 "StringNotLike" => Ok(IAMOperator::StringNotLike),
558 "ForAllValues:StringEquals" => Ok(IAMOperator::ForAllValuesStringEquals),
559 "ForAllValues:StringEqualsIgnoreCase" => {
560 Ok(IAMOperator::ForAllValuesStringEqualsIgnoreCase)
561 }
562 "ForAnyValue:StringEquals" => Ok(IAMOperator::ForAnyValueStringEquals),
563 "ForAnyValue:StringEqualsIgnoreCase" => {
564 Ok(IAMOperator::ForAnyValueStringEqualsIgnoreCase)
565 }
566 "ForAllValues:StringNotEquals" => Ok(IAMOperator::ForAllValuesStringNotEquals),
567 "ForAllValues:StringNotEqualsIgnoreCase" => {
568 Ok(IAMOperator::ForAllValuesStringNotEqualsIgnoreCase)
569 }
570 "ForAnyValue:StringNotEquals" => Ok(IAMOperator::ForAnyValueStringNotEquals),
571 "ForAnyValue:StringNotEqualsIgnoreCase" => {
572 Ok(IAMOperator::ForAnyValueStringNotEqualsIgnoreCase)
573 }
574 "ForAllValues:StringLike" => Ok(IAMOperator::ForAllValuesStringLike),
575 "ForAnyValue:StringLike" => Ok(IAMOperator::ForAnyValueStringLike),
576 "ForAllValues:StringNotLike" => Ok(IAMOperator::ForAllValuesStringNotLike),
577 "ForAnyValue:StringNotLike" => Ok(IAMOperator::ForAnyValueStringNotLike),
578 "NumericEquals" => Ok(IAMOperator::NumericEquals),
579 "NumericNotEquals" => Ok(IAMOperator::NumericNotEquals),
580 "NumericLessThan" => Ok(IAMOperator::NumericLessThan),
581 "NumericLessThanEquals" => Ok(IAMOperator::NumericLessThanEquals),
582 "NumericGreaterThan" => Ok(IAMOperator::NumericGreaterThan),
583 "NumericGreaterThanEquals" => Ok(IAMOperator::NumericGreaterThanEquals),
584 "DateEquals" => Ok(IAMOperator::DateEquals),
585 "DateNotEquals" => Ok(IAMOperator::DateNotEquals),
586 "DateLessThan" => Ok(IAMOperator::DateLessThan),
587 "DateLessThanEquals" => Ok(IAMOperator::DateLessThanEquals),
588 "DateGreaterThan" => Ok(IAMOperator::DateGreaterThan),
589 "DateGreaterThanEquals" => Ok(IAMOperator::DateGreaterThanEquals),
590 "Bool" => Ok(IAMOperator::Bool),
591 "ForAllValues:Bool" => Ok(IAMOperator::ForAllValuesBool),
592 "ForAnyValue:Bool" => Ok(IAMOperator::ForAnyValueBool),
593 "BinaryEquals" => Ok(IAMOperator::BinaryEquals),
594 "IpAddress" => Ok(IAMOperator::IpAddress),
595 "NotIpAddress" => Ok(IAMOperator::NotIpAddress),
596 "ArnEquals" => Ok(IAMOperator::ArnEquals),
597 "ArnLike" => Ok(IAMOperator::ArnLike),
598 "ArnNotEquals" => Ok(IAMOperator::ArnNotEquals),
599 "ArnNotLike" => Ok(IAMOperator::ArnNotLike),
600 "ForAllValues:ArnEquals" => Ok(IAMOperator::ForAllValuesArnEquals),
601 "ForAllValues:ArnLike" => Ok(IAMOperator::ForAllValuesArnLike),
602 "ForAnyValue:ArnEquals" => Ok(IAMOperator::ForAnyValueArnEquals),
603 "ForAnyValue:ArnLike" => Ok(IAMOperator::ForAnyValueArnLike),
604 "ForAllValues:ArnNotEquals" => Ok(IAMOperator::ForAllValuesArnNotEquals),
605 "ForAllValues:ArnNotLike" => Ok(IAMOperator::ForAllValuesArnNotLike),
606 "ForAnyValue:ArnNotEquals" => Ok(IAMOperator::ForAnyValueArnNotEquals),
607 "ForAnyValue:ArnNotLike" => Ok(IAMOperator::ForAnyValueArnNotLike),
608 "Null" => Ok(IAMOperator::Null),
609 "StringEqualsIfExists" => Ok(IAMOperator::StringEqualsIfExists),
610 "StringNotEqualsIfExists" => Ok(IAMOperator::StringNotEqualsIfExists),
611 "StringEqualsIgnoreCaseIfExists" => Ok(IAMOperator::StringEqualsIgnoreCaseIfExists),
612 "StringNotEqualsIgnoreCaseIfExists" => {
613 Ok(IAMOperator::StringNotEqualsIgnoreCaseIfExists)
614 }
615 "StringLikeIfExists" => Ok(IAMOperator::StringLikeIfExists),
616 "StringNotLikeIfExists" => Ok(IAMOperator::StringNotLikeIfExists),
617 "NumericEqualsIfExists" => Ok(IAMOperator::NumericEqualsIfExists),
618 "NumericNotEqualsIfExists" => Ok(IAMOperator::NumericNotEqualsIfExists),
619 "NumericLessThanIfExists" => Ok(IAMOperator::NumericLessThanIfExists),
620 "NumericLessThanEqualsIfExists" => Ok(IAMOperator::NumericLessThanEqualsIfExists),
621 "NumericGreaterThanIfExists" => Ok(IAMOperator::NumericGreaterThanIfExists),
622 "NumericGreaterThanEqualsIfExists" => Ok(IAMOperator::NumericGreaterThanEqualsIfExists),
623 "DateEqualsIfExists" => Ok(IAMOperator::DateEqualsIfExists),
624 "DateNotEqualsIfExists" => Ok(IAMOperator::DateNotEqualsIfExists),
625 "DateLessThanIfExists" => Ok(IAMOperator::DateLessThanIfExists),
626 "DateLessThanEqualsIfExists" => Ok(IAMOperator::DateLessThanEqualsIfExists),
627 "DateGreaterThanIfExists" => Ok(IAMOperator::DateGreaterThanIfExists),
628 "DateGreaterThanEqualsIfExists" => Ok(IAMOperator::DateGreaterThanEqualsIfExists),
629 "BoolIfExists" => Ok(IAMOperator::BoolIfExists),
630 "BinaryEqualsIfExists" => Ok(IAMOperator::BinaryEqualsIfExists),
631 "IpAddressIfExists" => Ok(IAMOperator::IpAddressIfExists),
632 "NotIpAddressIfExists" => Ok(IAMOperator::NotIpAddressIfExists),
633 "ArnEqualsIfExists" => Ok(IAMOperator::ArnEqualsIfExists),
634 "ArnLikeIfExists" => Ok(IAMOperator::ArnLikeIfExists),
635 "ArnNotEqualsIfExists" => Ok(IAMOperator::ArnNotEqualsIfExists),
636 "ArnNotLikeIfExists" => Ok(IAMOperator::ArnNotLikeIfExists),
637 _ => Err(format!("Unknown operator: {s}")),
638 }
639 }
640}
641
642#[cfg(test)]
643mod tests {
644 use super::*;
645 use serde_json;
646
647 #[test]
648 fn test_operator_serialization() {
649 let operator = IAMOperator::StringEquals;
650 let json = serde_json::to_string(&operator).unwrap();
651 assert_eq!(json, "\"StringEquals\"");
652
653 let deserialized: IAMOperator = serde_json::from_str(&json).unwrap();
654 assert_eq!(operator, deserialized);
655 }
656
657 #[test]
658 fn test_multivalued_operators() {
659 let operator = IAMOperator::ForAllValuesStringEquals;
660 let json = serde_json::to_string(&operator).unwrap();
661 assert_eq!(json, "\"ForAllValues:StringEquals\"");
662
663 let deserialized: IAMOperator = serde_json::from_str(&json).unwrap();
664 assert_eq!(operator, deserialized);
665 }
666
667 #[test]
668 fn test_operator_categories() {
669 assert!(IAMOperator::StringEquals.is_string_operator());
670 assert!(IAMOperator::NumericEquals.is_numeric_operator());
671 assert!(IAMOperator::DateEquals.is_date_operator());
672 assert!(IAMOperator::Bool.is_boolean_operator());
673 assert!(IAMOperator::ArnEquals.is_arn_operator());
674 assert!(IAMOperator::IpAddress.is_ip_operator());
675 assert!(IAMOperator::BinaryEquals.is_binary_operator());
676 }
677
678 #[test]
679 fn test_operator_features() {
680 assert!(IAMOperator::StringLike.supports_wildcards());
681 assert!(IAMOperator::StringEquals.supports_policy_variables());
682 assert!(!IAMOperator::NumericEquals.supports_policy_variables());
683 assert!(IAMOperator::ForAllValuesStringEquals.is_multivalued_operator());
684 assert!(IAMOperator::StringEqualsIfExists.is_if_exists_operator());
685 assert!(IAMOperator::StringNotEquals.is_negated_operator());
686
687 assert!(IAMOperator::StringEquals.supports_multiple_values());
689 assert!(IAMOperator::StringNotEquals.supports_multiple_values());
690 assert!(IAMOperator::NumericEquals.supports_multiple_values());
691 assert!(IAMOperator::DateEquals.supports_multiple_values());
692 assert!(IAMOperator::IpAddress.supports_multiple_values());
693 assert!(IAMOperator::ArnEquals.supports_multiple_values());
694
695 assert!(!IAMOperator::Bool.supports_multiple_values());
697 assert!(!IAMOperator::BoolIfExists.supports_multiple_values());
698 assert!(!IAMOperator::Null.supports_multiple_values());
699 }
700
701 #[test]
702 fn test_operator_category_strings() {
703 assert_eq!(IAMOperator::StringEquals.category(), OperatorType::String);
704 assert_eq!(IAMOperator::NumericEquals.category(), OperatorType::Numeric);
705 assert_eq!(IAMOperator::DateEquals.category(), OperatorType::Date);
706 assert_eq!(IAMOperator::Bool.category(), OperatorType::Boolean);
707 assert_eq!(IAMOperator::BinaryEquals.category(), OperatorType::Binary);
708 assert_eq!(IAMOperator::IpAddress.category(), OperatorType::IpAddress);
709 assert_eq!(IAMOperator::ArnEquals.category(), OperatorType::Arn);
710 assert_eq!(IAMOperator::Null.category(), OperatorType::Null);
711 }
712
713 #[test]
714 fn test_operator_string_conversion() {
715 assert_eq!(IAMOperator::StringEquals.as_str(), "StringEquals");
716 assert_eq!(
717 IAMOperator::ForAllValuesStringEquals.as_str(),
718 "ForAllValues:StringEquals"
719 );
720 assert_eq!(
721 IAMOperator::StringEqualsIfExists.as_str(),
722 "StringEqualsIfExists"
723 );
724 }
725
726 #[test]
727 fn test_operator_from_str() {
728 assert_eq!(
729 "StringEquals".parse::<IAMOperator>().unwrap(),
730 IAMOperator::StringEquals
731 );
732 assert_eq!(
733 "ForAllValues:StringEquals".parse::<IAMOperator>().unwrap(),
734 IAMOperator::ForAllValuesStringEquals
735 );
736 assert_eq!(
737 "StringEqualsIfExists".parse::<IAMOperator>().unwrap(),
738 IAMOperator::StringEqualsIfExists
739 );
740
741 assert!("InvalidOperator".parse::<IAMOperator>().is_err());
742 }
743}