1use serde::{Deserialize, Serialize};
2use std::collections::{HashMap, HashSet};
3
4#[derive(Debug, Default, Serialize, Deserialize)]
5pub struct KnownResourceTypes {
6 pub known_resource_types: Vec<String>,
7}
8
9#[derive(Debug, Default, Serialize, Deserialize)]
11pub struct GetattData {
12 pub getatt_attributes: HashMap<String, Vec<String>>,
13 pub getatt_attribute_types: HashMap<String, HashMap<String, String>>,
14}
15
16#[derive(Debug, Default, Serialize, Deserialize)]
17pub struct StatefulResourceTypes {
18 pub stateful_resource_types: HashSet<String>,
19}
20
21#[derive(Debug, Default, Serialize, Deserialize)]
22pub struct RetentionPeriodRequirements {
23 pub retention_period_requirements: HashMap<String, Vec<String>>,
24}
25
26#[derive(Debug, Default, Serialize, Deserialize)]
27pub struct PrimaryIdentifiers {
28 pub primary_identifiers: HashMap<String, Vec<String>>,
29}
30
31#[derive(Debug, Default, Serialize, Deserialize)]
32pub struct IamActionResourcePatterns {
33 pub iam_action_resource_patterns: HashMap<String, Vec<String>>,
34}
35
36#[derive(Debug, Default, Serialize, Deserialize)]
37pub struct CodepipelineArtifactCounts {
38 pub codepipeline_action_artifact_counts: HashMap<String, ArtifactCountEntry>,
39}
40
41#[derive(Debug, Default, Clone, Serialize, Deserialize)]
42pub struct ArtifactCountEntry {
43 pub min_input: usize,
44 pub max_input: usize,
45 pub min_output: usize,
46 pub max_output: usize,
47}
48
49#[derive(Debug, Default, Serialize, Deserialize)]
50pub struct DeprecatedResourceTypes {
51 pub deprecated_resource_types: Vec<String>,
52}
53
54#[derive(Debug, Default, Serialize, Deserialize)]
55pub struct SensitivePorts {
56 pub sensitive_ports: Vec<u16>,
57}
58
59#[derive(Debug, Default, Serialize, Deserialize)]
60pub struct SecretsManagerArnFields {
61 pub secretsmanager_arn_fields: Vec<String>,
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn required_document_fields_must_be_present() {
70 assert!(serde_json::from_str::<KnownResourceTypes>("{}").is_err());
71 assert!(serde_json::from_str::<GetattData>("{}").is_err());
72 assert!(serde_json::from_str::<StatefulResourceTypes>("{}").is_err());
73 assert!(serde_json::from_str::<RetentionPeriodRequirements>("{}").is_err());
74 assert!(serde_json::from_str::<PrimaryIdentifiers>("{}").is_err());
75 assert!(serde_json::from_str::<IamActionResourcePatterns>("{}").is_err());
76 assert!(serde_json::from_str::<CodepipelineArtifactCounts>("{}").is_err());
77 assert!(serde_json::from_str::<DeprecatedResourceTypes>("{}").is_err());
78 assert!(serde_json::from_str::<SensitivePorts>("{}").is_err());
79 assert!(serde_json::from_str::<SecretsManagerArnFields>("{}").is_err());
80 }
81
82 #[test]
83 fn postcard_roundtrip_known_resource_types() {
84 let original =
85 KnownResourceTypes { known_resource_types: vec!["AWS::S3::Bucket".into(), "AWS::EC2::Instance".into()] };
86 let bytes = postcard::to_allocvec(&original).unwrap();
87 let restored: KnownResourceTypes = postcard::from_bytes(&bytes).unwrap();
88 assert_eq!(restored.known_resource_types.len(), 2);
89 assert!(restored.known_resource_types.contains(&"AWS::S3::Bucket".to_string()));
90 }
91
92 #[test]
93 fn postcard_roundtrip_getatt_data() {
94 let mut original = GetattData::default();
95 original.getatt_attributes.insert("AWS::S3::Bucket".into(), vec!["Arn".into(), "DomainName".into()]);
96 original
97 .getatt_attribute_types
98 .insert("AWS::EC2::CapacityReservation".into(), [("InstanceCount".into(), "integer".into())].into());
99 let bytes = postcard::to_allocvec(&original).unwrap();
100 let restored: GetattData = postcard::from_bytes(&bytes).unwrap();
101 assert_eq!(restored.getatt_attributes["AWS::S3::Bucket"].len(), 2);
102 assert_eq!(restored.getatt_attribute_types["AWS::EC2::CapacityReservation"]["InstanceCount"], "integer");
103 }
104
105 #[test]
106 fn postcard_roundtrip_stateful_resource_types() {
107 let original = StatefulResourceTypes {
108 stateful_resource_types: ["AWS::SQS::Queue".into(), "AWS::DynamoDB::Table".into()].into(),
109 };
110 let bytes = postcard::to_allocvec(&original).unwrap();
111 let restored: StatefulResourceTypes = postcard::from_bytes(&bytes).unwrap();
112 assert!(restored.stateful_resource_types.contains("AWS::SQS::Queue"));
113 }
114
115 #[test]
116 fn postcard_roundtrip_retention_period_requirements() {
117 let original = RetentionPeriodRequirements {
118 retention_period_requirements: [("AWS::SQS::Queue".into(), vec!["MessageRetentionPeriod".into()])].into(),
119 };
120 let bytes = postcard::to_allocvec(&original).unwrap();
121 let restored: RetentionPeriodRequirements = postcard::from_bytes(&bytes).unwrap();
122 assert_eq!(restored.retention_period_requirements["AWS::SQS::Queue"], vec!["MessageRetentionPeriod"]);
123 }
124}