1use crate::validation::{Validate, ValidationContext, ValidationResult, helpers};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(untagged)]
7pub enum Action {
8 Single(String),
10 Multiple(Vec<String>),
12}
13
14impl Validate for Action {
15 fn validate(&self, context: &mut ValidationContext) -> ValidationResult {
16 context.with_segment("Action", |ctx| match self {
17 Action::Single(action) => helpers::validate_action(action, ctx),
18 Action::Multiple(actions) => {
19 if actions.is_empty() {
20 return Err(crate::validation::ValidationError::InvalidValue {
21 field: "Action".to_string(),
22 value: "[]".to_string(),
23 reason: "Action list cannot be empty".to_string(),
24 });
25 }
26
27 let results: Vec<ValidationResult> = actions
28 .iter()
29 .enumerate()
30 .map(|(i, action)| {
31 ctx.with_segment(&format!("[{}]", i), |nested_ctx| {
32 helpers::validate_action(action, nested_ctx)
33 })
34 })
35 .collect();
36
37 helpers::collect_errors(results)
38 }
39 })
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn test_action_validation() {
49 let valid_single = Action::Single("s3:GetObject".to_string());
50 assert!(valid_single.is_valid());
51
52 let valid_wildcard = Action::Single("*".to_string());
53 assert!(valid_wildcard.is_valid());
54
55 let valid_multiple =
56 Action::Multiple(vec!["s3:GetObject".to_string(), "s3:PutObject".to_string()]);
57 assert!(valid_multiple.is_valid());
58
59 let invalid_single = Action::Single("invalid-action".to_string());
60 assert!(!invalid_single.is_valid());
61
62 let empty_multiple = Action::Multiple(vec![]);
63 assert!(!empty_multiple.is_valid());
64
65 let invalid_multiple = Action::Multiple(vec![
66 "s3:GetObject".to_string(),
67 "invalid-action".to_string(),
68 ]);
69 assert!(!invalid_multiple.is_valid());
70 }
71}