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]
361 pub fn supports_policy_variables(&self) -> bool {
362 self.is_string_operator() || self.is_arn_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 #[allow(clippy::too_many_lines)]
431 #[must_use]
432 pub fn category(&self) -> OperatorType {
433 match self {
434 IAMOperator::StringEquals
436 | IAMOperator::StringNotEquals
437 | IAMOperator::StringEqualsIgnoreCase
438 | IAMOperator::StringNotEqualsIgnoreCase
439 | IAMOperator::StringLike
440 | IAMOperator::StringNotLike
441 | IAMOperator::ForAllValuesStringEquals
442 | IAMOperator::ForAllValuesStringEqualsIgnoreCase
443 | IAMOperator::ForAnyValueStringEquals
444 | IAMOperator::ForAnyValueStringEqualsIgnoreCase
445 | IAMOperator::ForAllValuesStringNotEquals
446 | IAMOperator::ForAllValuesStringNotEqualsIgnoreCase
447 | IAMOperator::ForAnyValueStringNotEquals
448 | IAMOperator::ForAnyValueStringNotEqualsIgnoreCase
449 | IAMOperator::ForAllValuesStringLike
450 | IAMOperator::ForAnyValueStringLike
451 | IAMOperator::ForAllValuesStringNotLike
452 | IAMOperator::ForAnyValueStringNotLike
453 | IAMOperator::StringEqualsIfExists
454 | IAMOperator::StringNotEqualsIfExists
455 | IAMOperator::StringEqualsIgnoreCaseIfExists
456 | IAMOperator::StringNotEqualsIgnoreCaseIfExists
457 | IAMOperator::StringLikeIfExists
458 | IAMOperator::StringNotLikeIfExists => OperatorType::String,
459
460 IAMOperator::NumericEquals
462 | IAMOperator::NumericNotEquals
463 | IAMOperator::NumericLessThan
464 | IAMOperator::NumericLessThanEquals
465 | IAMOperator::NumericGreaterThan
466 | IAMOperator::NumericGreaterThanEquals
467 | IAMOperator::NumericEqualsIfExists
468 | IAMOperator::NumericNotEqualsIfExists
469 | IAMOperator::NumericLessThanIfExists
470 | IAMOperator::NumericLessThanEqualsIfExists
471 | IAMOperator::NumericGreaterThanIfExists
472 | IAMOperator::NumericGreaterThanEqualsIfExists => OperatorType::Numeric,
473
474 IAMOperator::DateEquals
476 | IAMOperator::DateNotEquals
477 | IAMOperator::DateLessThan
478 | IAMOperator::DateLessThanEquals
479 | IAMOperator::DateGreaterThan
480 | IAMOperator::DateGreaterThanEquals
481 | IAMOperator::DateEqualsIfExists
482 | IAMOperator::DateNotEqualsIfExists
483 | IAMOperator::DateLessThanIfExists
484 | IAMOperator::DateLessThanEqualsIfExists
485 | IAMOperator::DateGreaterThanIfExists
486 | IAMOperator::DateGreaterThanEqualsIfExists => OperatorType::Date,
487
488 IAMOperator::Bool
490 | IAMOperator::ForAllValuesBool
491 | IAMOperator::ForAnyValueBool
492 | IAMOperator::BoolIfExists => OperatorType::Boolean,
493
494 IAMOperator::BinaryEquals | IAMOperator::BinaryEqualsIfExists => OperatorType::Binary,
496
497 IAMOperator::IpAddress
499 | IAMOperator::NotIpAddress
500 | IAMOperator::IpAddressIfExists
501 | IAMOperator::NotIpAddressIfExists => OperatorType::IpAddress,
502
503 IAMOperator::ArnEquals
505 | IAMOperator::ArnLike
506 | IAMOperator::ArnNotEquals
507 | IAMOperator::ArnNotLike
508 | IAMOperator::ForAllValuesArnEquals
509 | IAMOperator::ForAllValuesArnLike
510 | IAMOperator::ForAnyValueArnEquals
511 | IAMOperator::ForAnyValueArnLike
512 | IAMOperator::ForAllValuesArnNotEquals
513 | IAMOperator::ForAllValuesArnNotLike
514 | IAMOperator::ForAnyValueArnNotEquals
515 | IAMOperator::ForAnyValueArnNotLike
516 | IAMOperator::ArnEqualsIfExists
517 | IAMOperator::ArnLikeIfExists
518 | IAMOperator::ArnNotEqualsIfExists
519 | IAMOperator::ArnNotLikeIfExists => OperatorType::Arn,
520
521 IAMOperator::Null => OperatorType::Null,
523 }
524 }
525
526 #[must_use]
528 pub fn as_str(&self) -> &'static str {
529 match self {
530 IAMOperator::StringEquals => "StringEquals",
531 IAMOperator::StringNotEquals => "StringNotEquals",
532 IAMOperator::StringEqualsIgnoreCase => "StringEqualsIgnoreCase",
533 IAMOperator::StringNotEqualsIgnoreCase => "StringNotEqualsIgnoreCase",
534 IAMOperator::StringLike => "StringLike",
535 IAMOperator::StringNotLike => "StringNotLike",
536 IAMOperator::ForAllValuesStringEquals => "ForAllValues:StringEquals",
537 IAMOperator::ForAllValuesStringEqualsIgnoreCase => {
538 "ForAllValues:StringEqualsIgnoreCase"
539 }
540 IAMOperator::ForAnyValueStringEquals => "ForAnyValue:StringEquals",
541 IAMOperator::ForAnyValueStringEqualsIgnoreCase => "ForAnyValue:StringEqualsIgnoreCase",
542 IAMOperator::ForAllValuesStringNotEquals => "ForAllValues:StringNotEquals",
543 IAMOperator::ForAllValuesStringNotEqualsIgnoreCase => {
544 "ForAllValues:StringNotEqualsIgnoreCase"
545 }
546 IAMOperator::ForAnyValueStringNotEquals => "ForAnyValue:StringNotEquals",
547 IAMOperator::ForAnyValueStringNotEqualsIgnoreCase => {
548 "ForAnyValue:StringNotEqualsIgnoreCase"
549 }
550 IAMOperator::ForAllValuesStringLike => "ForAllValues:StringLike",
551 IAMOperator::ForAnyValueStringLike => "ForAnyValue:StringLike",
552 IAMOperator::ForAllValuesStringNotLike => "ForAllValues:StringNotLike",
553 IAMOperator::ForAnyValueStringNotLike => "ForAnyValue:StringNotLike",
554 IAMOperator::NumericEquals => "NumericEquals",
555 IAMOperator::NumericNotEquals => "NumericNotEquals",
556 IAMOperator::NumericLessThan => "NumericLessThan",
557 IAMOperator::NumericLessThanEquals => "NumericLessThanEquals",
558 IAMOperator::NumericGreaterThan => "NumericGreaterThan",
559 IAMOperator::NumericGreaterThanEquals => "NumericGreaterThanEquals",
560 IAMOperator::DateEquals => "DateEquals",
561 IAMOperator::DateNotEquals => "DateNotEquals",
562 IAMOperator::DateLessThan => "DateLessThan",
563 IAMOperator::DateLessThanEquals => "DateLessThanEquals",
564 IAMOperator::DateGreaterThan => "DateGreaterThan",
565 IAMOperator::DateGreaterThanEquals => "DateGreaterThanEquals",
566 IAMOperator::Bool => "Bool",
567 IAMOperator::ForAllValuesBool => "ForAllValues:Bool",
568 IAMOperator::ForAnyValueBool => "ForAnyValue:Bool",
569 IAMOperator::BinaryEquals => "BinaryEquals",
570 IAMOperator::IpAddress => "IpAddress",
571 IAMOperator::NotIpAddress => "NotIpAddress",
572 IAMOperator::ArnEquals => "ArnEquals",
573 IAMOperator::ArnLike => "ArnLike",
574 IAMOperator::ArnNotEquals => "ArnNotEquals",
575 IAMOperator::ArnNotLike => "ArnNotLike",
576 IAMOperator::ForAllValuesArnEquals => "ForAllValues:ArnEquals",
577 IAMOperator::ForAllValuesArnLike => "ForAllValues:ArnLike",
578 IAMOperator::ForAnyValueArnEquals => "ForAnyValue:ArnEquals",
579 IAMOperator::ForAnyValueArnLike => "ForAnyValue:ArnLike",
580 IAMOperator::ForAllValuesArnNotEquals => "ForAllValues:ArnNotEquals",
581 IAMOperator::ForAllValuesArnNotLike => "ForAllValues:ArnNotLike",
582 IAMOperator::ForAnyValueArnNotEquals => "ForAnyValue:ArnNotEquals",
583 IAMOperator::ForAnyValueArnNotLike => "ForAnyValue:ArnNotLike",
584 IAMOperator::Null => "Null",
585 IAMOperator::StringEqualsIfExists => "StringEqualsIfExists",
586 IAMOperator::StringNotEqualsIfExists => "StringNotEqualsIfExists",
587 IAMOperator::StringEqualsIgnoreCaseIfExists => "StringEqualsIgnoreCaseIfExists",
588 IAMOperator::StringNotEqualsIgnoreCaseIfExists => "StringNotEqualsIgnoreCaseIfExists",
589 IAMOperator::StringLikeIfExists => "StringLikeIfExists",
590 IAMOperator::StringNotLikeIfExists => "StringNotLikeIfExists",
591 IAMOperator::NumericEqualsIfExists => "NumericEqualsIfExists",
592 IAMOperator::NumericNotEqualsIfExists => "NumericNotEqualsIfExists",
593 IAMOperator::NumericLessThanIfExists => "NumericLessThanIfExists",
594 IAMOperator::NumericLessThanEqualsIfExists => "NumericLessThanEqualsIfExists",
595 IAMOperator::NumericGreaterThanIfExists => "NumericGreaterThanIfExists",
596 IAMOperator::NumericGreaterThanEqualsIfExists => "NumericGreaterThanEqualsIfExists",
597 IAMOperator::DateEqualsIfExists => "DateEqualsIfExists",
598 IAMOperator::DateNotEqualsIfExists => "DateNotEqualsIfExists",
599 IAMOperator::DateLessThanIfExists => "DateLessThanIfExists",
600 IAMOperator::DateLessThanEqualsIfExists => "DateLessThanEqualsIfExists",
601 IAMOperator::DateGreaterThanIfExists => "DateGreaterThanIfExists",
602 IAMOperator::DateGreaterThanEqualsIfExists => "DateGreaterThanEqualsIfExists",
603 IAMOperator::BoolIfExists => "BoolIfExists",
604 IAMOperator::BinaryEqualsIfExists => "BinaryEqualsIfExists",
605 IAMOperator::IpAddressIfExists => "IpAddressIfExists",
606 IAMOperator::NotIpAddressIfExists => "NotIpAddressIfExists",
607 IAMOperator::ArnEqualsIfExists => "ArnEqualsIfExists",
608 IAMOperator::ArnLikeIfExists => "ArnLikeIfExists",
609 IAMOperator::ArnNotEqualsIfExists => "ArnNotEqualsIfExists",
610 IAMOperator::ArnNotLikeIfExists => "ArnNotLikeIfExists",
611 }
612 }
613}
614
615impl std::fmt::Display for IAMOperator {
616 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
617 write!(f, "{}", self.as_str())
618 }
619}
620
621impl std::str::FromStr for IAMOperator {
622 type Err = String;
623
624 fn from_str(s: &str) -> Result<Self, Self::Err> {
625 match s {
626 "StringEquals" => Ok(IAMOperator::StringEquals),
627 "StringNotEquals" => Ok(IAMOperator::StringNotEquals),
628 "StringEqualsIgnoreCase" => Ok(IAMOperator::StringEqualsIgnoreCase),
629 "StringNotEqualsIgnoreCase" => Ok(IAMOperator::StringNotEqualsIgnoreCase),
630 "StringLike" => Ok(IAMOperator::StringLike),
631 "StringNotLike" => Ok(IAMOperator::StringNotLike),
632 "ForAllValues:StringEquals" => Ok(IAMOperator::ForAllValuesStringEquals),
633 "ForAllValues:StringEqualsIgnoreCase" => {
634 Ok(IAMOperator::ForAllValuesStringEqualsIgnoreCase)
635 }
636 "ForAnyValue:StringEquals" => Ok(IAMOperator::ForAnyValueStringEquals),
637 "ForAnyValue:StringEqualsIgnoreCase" => {
638 Ok(IAMOperator::ForAnyValueStringEqualsIgnoreCase)
639 }
640 "ForAllValues:StringNotEquals" => Ok(IAMOperator::ForAllValuesStringNotEquals),
641 "ForAllValues:StringNotEqualsIgnoreCase" => {
642 Ok(IAMOperator::ForAllValuesStringNotEqualsIgnoreCase)
643 }
644 "ForAnyValue:StringNotEquals" => Ok(IAMOperator::ForAnyValueStringNotEquals),
645 "ForAnyValue:StringNotEqualsIgnoreCase" => {
646 Ok(IAMOperator::ForAnyValueStringNotEqualsIgnoreCase)
647 }
648 "ForAllValues:StringLike" => Ok(IAMOperator::ForAllValuesStringLike),
649 "ForAnyValue:StringLike" => Ok(IAMOperator::ForAnyValueStringLike),
650 "ForAllValues:StringNotLike" => Ok(IAMOperator::ForAllValuesStringNotLike),
651 "ForAnyValue:StringNotLike" => Ok(IAMOperator::ForAnyValueStringNotLike),
652 "NumericEquals" => Ok(IAMOperator::NumericEquals),
653 "NumericNotEquals" => Ok(IAMOperator::NumericNotEquals),
654 "NumericLessThan" => Ok(IAMOperator::NumericLessThan),
655 "NumericLessThanEquals" => Ok(IAMOperator::NumericLessThanEquals),
656 "NumericGreaterThan" => Ok(IAMOperator::NumericGreaterThan),
657 "NumericGreaterThanEquals" => Ok(IAMOperator::NumericGreaterThanEquals),
658 "DateEquals" => Ok(IAMOperator::DateEquals),
659 "DateNotEquals" => Ok(IAMOperator::DateNotEquals),
660 "DateLessThan" => Ok(IAMOperator::DateLessThan),
661 "DateLessThanEquals" => Ok(IAMOperator::DateLessThanEquals),
662 "DateGreaterThan" => Ok(IAMOperator::DateGreaterThan),
663 "DateGreaterThanEquals" => Ok(IAMOperator::DateGreaterThanEquals),
664 "Bool" => Ok(IAMOperator::Bool),
665 "ForAllValues:Bool" => Ok(IAMOperator::ForAllValuesBool),
666 "ForAnyValue:Bool" => Ok(IAMOperator::ForAnyValueBool),
667 "BinaryEquals" => Ok(IAMOperator::BinaryEquals),
668 "IpAddress" => Ok(IAMOperator::IpAddress),
669 "NotIpAddress" => Ok(IAMOperator::NotIpAddress),
670 "ArnEquals" => Ok(IAMOperator::ArnEquals),
671 "ArnLike" => Ok(IAMOperator::ArnLike),
672 "ArnNotEquals" => Ok(IAMOperator::ArnNotEquals),
673 "ArnNotLike" => Ok(IAMOperator::ArnNotLike),
674 "ForAllValues:ArnEquals" => Ok(IAMOperator::ForAllValuesArnEquals),
675 "ForAllValues:ArnLike" => Ok(IAMOperator::ForAllValuesArnLike),
676 "ForAnyValue:ArnEquals" => Ok(IAMOperator::ForAnyValueArnEquals),
677 "ForAnyValue:ArnLike" => Ok(IAMOperator::ForAnyValueArnLike),
678 "ForAllValues:ArnNotEquals" => Ok(IAMOperator::ForAllValuesArnNotEquals),
679 "ForAllValues:ArnNotLike" => Ok(IAMOperator::ForAllValuesArnNotLike),
680 "ForAnyValue:ArnNotEquals" => Ok(IAMOperator::ForAnyValueArnNotEquals),
681 "ForAnyValue:ArnNotLike" => Ok(IAMOperator::ForAnyValueArnNotLike),
682 "Null" => Ok(IAMOperator::Null),
683 "StringEqualsIfExists" => Ok(IAMOperator::StringEqualsIfExists),
684 "StringNotEqualsIfExists" => Ok(IAMOperator::StringNotEqualsIfExists),
685 "StringEqualsIgnoreCaseIfExists" => Ok(IAMOperator::StringEqualsIgnoreCaseIfExists),
686 "StringNotEqualsIgnoreCaseIfExists" => {
687 Ok(IAMOperator::StringNotEqualsIgnoreCaseIfExists)
688 }
689 "StringLikeIfExists" => Ok(IAMOperator::StringLikeIfExists),
690 "StringNotLikeIfExists" => Ok(IAMOperator::StringNotLikeIfExists),
691 "NumericEqualsIfExists" => Ok(IAMOperator::NumericEqualsIfExists),
692 "NumericNotEqualsIfExists" => Ok(IAMOperator::NumericNotEqualsIfExists),
693 "NumericLessThanIfExists" => Ok(IAMOperator::NumericLessThanIfExists),
694 "NumericLessThanEqualsIfExists" => Ok(IAMOperator::NumericLessThanEqualsIfExists),
695 "NumericGreaterThanIfExists" => Ok(IAMOperator::NumericGreaterThanIfExists),
696 "NumericGreaterThanEqualsIfExists" => Ok(IAMOperator::NumericGreaterThanEqualsIfExists),
697 "DateEqualsIfExists" => Ok(IAMOperator::DateEqualsIfExists),
698 "DateNotEqualsIfExists" => Ok(IAMOperator::DateNotEqualsIfExists),
699 "DateLessThanIfExists" => Ok(IAMOperator::DateLessThanIfExists),
700 "DateLessThanEqualsIfExists" => Ok(IAMOperator::DateLessThanEqualsIfExists),
701 "DateGreaterThanIfExists" => Ok(IAMOperator::DateGreaterThanIfExists),
702 "DateGreaterThanEqualsIfExists" => Ok(IAMOperator::DateGreaterThanEqualsIfExists),
703 "BoolIfExists" => Ok(IAMOperator::BoolIfExists),
704 "BinaryEqualsIfExists" => Ok(IAMOperator::BinaryEqualsIfExists),
705 "IpAddressIfExists" => Ok(IAMOperator::IpAddressIfExists),
706 "NotIpAddressIfExists" => Ok(IAMOperator::NotIpAddressIfExists),
707 "ArnEqualsIfExists" => Ok(IAMOperator::ArnEqualsIfExists),
708 "ArnLikeIfExists" => Ok(IAMOperator::ArnLikeIfExists),
709 "ArnNotEqualsIfExists" => Ok(IAMOperator::ArnNotEqualsIfExists),
710 "ArnNotLikeIfExists" => Ok(IAMOperator::ArnNotLikeIfExists),
711 _ => Err(format!("Unknown operator: {s}")),
712 }
713 }
714}
715
716#[cfg(test)]
717mod tests {
718 use super::*;
719
720 #[test]
721 fn test_operator_serialization() {
722 let operator = IAMOperator::StringEquals;
723 let json = serde_json::to_string(&operator).unwrap();
724 assert_eq!(json, "\"StringEquals\"");
725
726 let deserialized: IAMOperator = serde_json::from_str(&json).unwrap();
727 assert_eq!(operator, deserialized);
728 }
729
730 #[test]
731 fn test_multivalued_operators() {
732 let operator = IAMOperator::ForAllValuesStringEquals;
733 let json = serde_json::to_string(&operator).unwrap();
734 assert_eq!(json, "\"ForAllValues:StringEquals\"");
735
736 let deserialized: IAMOperator = serde_json::from_str(&json).unwrap();
737 assert_eq!(operator, deserialized);
738 }
739
740 #[test]
741 fn test_operator_categories() {
742 assert!(IAMOperator::StringEquals.is_string_operator());
743 assert!(IAMOperator::NumericEquals.is_numeric_operator());
744 assert!(IAMOperator::DateEquals.is_date_operator());
745 assert!(IAMOperator::Bool.is_boolean_operator());
746 assert!(IAMOperator::ArnEquals.is_arn_operator());
747 assert!(IAMOperator::IpAddress.is_ip_operator());
748 assert!(IAMOperator::BinaryEquals.is_binary_operator());
749 }
750
751 #[test]
752 fn test_operator_features() {
753 assert!(IAMOperator::StringLike.supports_wildcards());
754 assert!(IAMOperator::StringEquals.supports_policy_variables());
755 assert!(!IAMOperator::NumericEquals.supports_policy_variables());
756 assert!(IAMOperator::ForAllValuesStringEquals.is_multivalued_operator());
757 assert!(IAMOperator::StringEqualsIfExists.is_if_exists_operator());
758 assert!(IAMOperator::StringNotEquals.is_negated_operator());
759
760 assert!(IAMOperator::StringEquals.supports_multiple_values());
762 assert!(IAMOperator::StringNotEquals.supports_multiple_values());
763 assert!(IAMOperator::NumericEquals.supports_multiple_values());
764 assert!(IAMOperator::DateEquals.supports_multiple_values());
765 assert!(IAMOperator::IpAddress.supports_multiple_values());
766 assert!(IAMOperator::ArnEquals.supports_multiple_values());
767
768 assert!(!IAMOperator::Bool.supports_multiple_values());
770 assert!(!IAMOperator::BoolIfExists.supports_multiple_values());
771 assert!(!IAMOperator::Null.supports_multiple_values());
772 }
773
774 #[test]
775 fn test_supports_policy_variables() {
776 assert!(IAMOperator::StringEquals.supports_policy_variables());
778 assert!(IAMOperator::StringLikeIfExists.supports_policy_variables());
779 assert!(IAMOperator::ArnLike.supports_policy_variables());
780 assert!(IAMOperator::ForAnyValueArnEquals.supports_policy_variables());
781
782 assert!(!IAMOperator::Bool.supports_policy_variables());
784 assert!(!IAMOperator::ForAllValuesBool.supports_policy_variables());
785 assert!(!IAMOperator::ForAnyValueBool.supports_policy_variables());
786 assert!(!IAMOperator::Null.supports_policy_variables());
787 assert!(!IAMOperator::NumericEquals.supports_policy_variables());
788 assert!(!IAMOperator::DateEquals.supports_policy_variables());
789 assert!(!IAMOperator::BinaryEquals.supports_policy_variables());
790 assert!(!IAMOperator::IpAddress.supports_policy_variables());
791 assert!(!IAMOperator::NotIpAddress.supports_policy_variables());
792 }
793
794 #[test]
795 fn test_operator_category_strings() {
796 assert_eq!(IAMOperator::StringEquals.category(), OperatorType::String);
797 assert_eq!(IAMOperator::NumericEquals.category(), OperatorType::Numeric);
798 assert_eq!(IAMOperator::DateEquals.category(), OperatorType::Date);
799 assert_eq!(IAMOperator::Bool.category(), OperatorType::Boolean);
800 assert_eq!(IAMOperator::BinaryEquals.category(), OperatorType::Binary);
801 assert_eq!(IAMOperator::IpAddress.category(), OperatorType::IpAddress);
802 assert_eq!(IAMOperator::ArnEquals.category(), OperatorType::Arn);
803 assert_eq!(IAMOperator::Null.category(), OperatorType::Null);
804 }
805
806 #[test]
807 #[allow(clippy::too_many_lines)]
808 fn test_operator_category_exhaustive() {
809 fn assert_category(ops: &[IAMOperator], expected: &OperatorType) {
814 for op in ops {
815 assert_eq!(&op.category(), expected, "operator {}", op.as_str());
816 }
817 }
818
819 assert_category(
820 &[
821 IAMOperator::StringEquals,
822 IAMOperator::StringNotEquals,
823 IAMOperator::StringEqualsIgnoreCase,
824 IAMOperator::StringNotEqualsIgnoreCase,
825 IAMOperator::StringLike,
826 IAMOperator::StringNotLike,
827 IAMOperator::ForAllValuesStringEquals,
828 IAMOperator::ForAllValuesStringEqualsIgnoreCase,
829 IAMOperator::ForAnyValueStringEquals,
830 IAMOperator::ForAnyValueStringEqualsIgnoreCase,
831 IAMOperator::ForAllValuesStringNotEquals,
832 IAMOperator::ForAllValuesStringNotEqualsIgnoreCase,
833 IAMOperator::ForAnyValueStringNotEquals,
834 IAMOperator::ForAnyValueStringNotEqualsIgnoreCase,
835 IAMOperator::ForAllValuesStringLike,
836 IAMOperator::ForAnyValueStringLike,
837 IAMOperator::ForAllValuesStringNotLike,
838 IAMOperator::ForAnyValueStringNotLike,
839 IAMOperator::StringEqualsIfExists,
840 IAMOperator::StringNotEqualsIfExists,
841 IAMOperator::StringEqualsIgnoreCaseIfExists,
842 IAMOperator::StringNotEqualsIgnoreCaseIfExists,
843 IAMOperator::StringLikeIfExists,
844 IAMOperator::StringNotLikeIfExists,
845 ],
846 &OperatorType::String,
847 );
848
849 assert_category(
850 &[
851 IAMOperator::NumericEquals,
852 IAMOperator::NumericNotEquals,
853 IAMOperator::NumericLessThan,
854 IAMOperator::NumericLessThanEquals,
855 IAMOperator::NumericGreaterThan,
856 IAMOperator::NumericGreaterThanEquals,
857 IAMOperator::NumericEqualsIfExists,
858 IAMOperator::NumericNotEqualsIfExists,
859 IAMOperator::NumericLessThanIfExists,
860 IAMOperator::NumericLessThanEqualsIfExists,
861 IAMOperator::NumericGreaterThanIfExists,
862 IAMOperator::NumericGreaterThanEqualsIfExists,
863 ],
864 &OperatorType::Numeric,
865 );
866
867 assert_category(
868 &[
869 IAMOperator::DateEquals,
870 IAMOperator::DateNotEquals,
871 IAMOperator::DateLessThan,
872 IAMOperator::DateLessThanEquals,
873 IAMOperator::DateGreaterThan,
874 IAMOperator::DateGreaterThanEquals,
875 IAMOperator::DateEqualsIfExists,
876 IAMOperator::DateNotEqualsIfExists,
877 IAMOperator::DateLessThanIfExists,
878 IAMOperator::DateLessThanEqualsIfExists,
879 IAMOperator::DateGreaterThanIfExists,
880 IAMOperator::DateGreaterThanEqualsIfExists,
881 ],
882 &OperatorType::Date,
883 );
884
885 assert_category(
886 &[
887 IAMOperator::Bool,
888 IAMOperator::ForAllValuesBool,
889 IAMOperator::ForAnyValueBool,
890 IAMOperator::BoolIfExists,
891 ],
892 &OperatorType::Boolean,
893 );
894
895 assert_category(
896 &[IAMOperator::BinaryEquals, IAMOperator::BinaryEqualsIfExists],
897 &OperatorType::Binary,
898 );
899
900 assert_category(
901 &[
902 IAMOperator::IpAddress,
903 IAMOperator::NotIpAddress,
904 IAMOperator::IpAddressIfExists,
905 IAMOperator::NotIpAddressIfExists,
906 ],
907 &OperatorType::IpAddress,
908 );
909
910 assert_category(
911 &[
912 IAMOperator::ArnEquals,
913 IAMOperator::ArnLike,
914 IAMOperator::ArnNotEquals,
915 IAMOperator::ArnNotLike,
916 IAMOperator::ForAllValuesArnEquals,
917 IAMOperator::ForAllValuesArnLike,
918 IAMOperator::ForAnyValueArnEquals,
919 IAMOperator::ForAnyValueArnLike,
920 IAMOperator::ForAllValuesArnNotEquals,
921 IAMOperator::ForAllValuesArnNotLike,
922 IAMOperator::ForAnyValueArnNotEquals,
923 IAMOperator::ForAnyValueArnNotLike,
924 IAMOperator::ArnEqualsIfExists,
925 IAMOperator::ArnLikeIfExists,
926 IAMOperator::ArnNotEqualsIfExists,
927 IAMOperator::ArnNotLikeIfExists,
928 ],
929 &OperatorType::Arn,
930 );
931
932 assert_category(&[IAMOperator::Null], &OperatorType::Null);
933 }
934
935 #[test]
936 fn test_operator_string_conversion() {
937 assert_eq!(IAMOperator::StringEquals.as_str(), "StringEquals");
938 assert_eq!(
939 IAMOperator::ForAllValuesStringEquals.as_str(),
940 "ForAllValues:StringEquals"
941 );
942 assert_eq!(
943 IAMOperator::StringEqualsIfExists.as_str(),
944 "StringEqualsIfExists"
945 );
946 }
947
948 #[test]
949 fn test_operator_from_str() {
950 assert_eq!(
951 "StringEquals".parse::<IAMOperator>().unwrap(),
952 IAMOperator::StringEquals
953 );
954 assert_eq!(
955 "ForAllValues:StringEquals".parse::<IAMOperator>().unwrap(),
956 IAMOperator::ForAllValuesStringEquals
957 );
958 assert_eq!(
959 "StringEqualsIfExists".parse::<IAMOperator>().unwrap(),
960 IAMOperator::StringEqualsIfExists
961 );
962
963 assert!("InvalidOperator".parse::<IAMOperator>().is_err());
964 }
965}