fakecloud_comprehend/
shared.rs1pub fn now_epoch() -> f64 {
9 chrono::Utc::now().timestamp_millis() as f64 / 1000.0
10}
11
12pub fn hash_str(s: &str) -> u64 {
15 let mut h: u64 = 0xcbf2_9ce4_8422_2325;
16 for b in s.as_bytes() {
17 h ^= u64::from(*b);
18 h = h.wrapping_mul(0x0000_0100_0000_01b3);
19 }
20 h
21}
22
23pub fn hex32(seed: &str) -> String {
26 if seed.is_empty() {
27 return uuid::Uuid::new_v4().simple().to_string();
28 }
29 let a = hash_str(seed);
30 let b = hash_str(&format!("{seed}/salt"));
31 format!("{a:016x}{b:016x}")
32}
33
34pub fn resource_arn(region: &str, account: &str, resource_type: &str, tail: &str) -> String {
41 format!("arn:aws:comprehend:{region}:{account}:{resource_type}/{tail}")
42}
43
44pub fn parse_resource_arn(arn: &str) -> Option<(String, String)> {
48 let mut parts = arn.splitn(6, ':');
49 let tail = parts.nth(5)?;
50 let (rtype, rest) = tail.split_once('/')?;
51 if rtype.is_empty() || rest.is_empty() {
52 return None;
53 }
54 Some((rtype.to_string(), rest.to_string()))
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn arn_round_trips() {
63 let arn = resource_arn("us-east-1", "000000000000", "flywheel", "my-fw");
64 assert_eq!(
65 arn,
66 "arn:aws:comprehend:us-east-1:000000000000:flywheel/my-fw"
67 );
68 assert_eq!(
69 parse_resource_arn(&arn),
70 Some(("flywheel".to_string(), "my-fw".to_string()))
71 );
72 }
73
74 #[test]
75 fn arn_keeps_versioned_tail() {
76 let arn = "arn:aws:comprehend:us-east-1:000000000000:document-classifier/name/version/v1";
77 assert_eq!(
78 parse_resource_arn(arn),
79 Some((
80 "document-classifier".to_string(),
81 "name/version/v1".to_string()
82 ))
83 );
84 }
85
86 #[test]
87 fn parse_rejects_non_comprehend() {
88 assert_eq!(parse_resource_arn("arn:aws:s3:::bucket"), None);
89 }
90
91 #[test]
92 fn hex32_is_stable_and_shaped() {
93 let a = hex32("seed");
94 let b = hex32("seed");
95 assert_eq!(a, b);
96 assert_eq!(a.len(), 32);
97 assert!(a.chars().all(|c| c.is_ascii_hexdigit()));
98 }
99}