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 Resource {
8 Single(String),
10 Multiple(Vec<String>),
12}
13
14impl Validate for Resource {
15 fn validate(&self, context: &mut ValidationContext) -> ValidationResult {
16 context.with_segment("Resource", |ctx| match self {
17 Resource::Single(resource) => helpers::validate_resource(resource, ctx),
18 Resource::Multiple(resources) => {
19 if resources.is_empty() {
20 return Err(crate::validation::ValidationError::InvalidValue {
21 field: "Resource".to_string(),
22 value: "[]".to_string(),
23 reason: "Resource list cannot be empty".to_string(),
24 });
25 }
26
27 let results: Vec<ValidationResult> = resources
28 .iter()
29 .enumerate()
30 .map(|(i, resource)| {
31 ctx.with_segment(&format!("[{}]", i), |nested_ctx| {
32 helpers::validate_resource(resource, 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_resource_validation() {
49 let valid_single = Resource::Single("arn:aws:s3:::bucket/*".to_string());
50 assert!(valid_single.is_valid());
51
52 let valid_wildcard = Resource::Single("*".to_string());
53 assert!(valid_wildcard.is_valid());
54
55 let valid_multiple = Resource::Multiple(vec![
56 "arn:aws:s3:::bucket/*".to_string(),
57 "arn:aws:s3:::other-bucket/*".to_string(),
58 ]);
59 assert!(valid_multiple.is_valid());
60
61 let invalid_single = Resource::Single("invalid-resource".to_string());
62 assert!(!invalid_single.is_valid());
63
64 let empty_multiple = Resource::Multiple(vec![]);
65 assert!(!empty_multiple.is_valid());
66
67 let invalid_multiple = Resource::Multiple(vec![
68 "arn:aws:s3:::bucket/*".to_string(),
69 "invalid-resource".to_string(),
70 ]);
71 assert!(!invalid_multiple.is_valid());
72 }
73
74 #[test]
75 fn test_resource_with_wildcards() {
76 let wildcard_resource = Resource::Single("arn:aws:s3:::*/*".to_string());
77 assert!(wildcard_resource.is_valid());
78
79 let complex_wildcard =
80 Resource::Single("arn:aws:s3:::bucket/folder/*/file.txt".to_string());
81 assert!(complex_wildcard.is_valid());
82 }
83}