1use uuid::Uuid;
4
5use crate::types::{DnsName, TypeError};
6
7pub fn compose_instance_name(stack: &str) -> Result<String, TypeError> {
9 let id = Uuid::new_v4().hyphenated().to_string();
10 let name = format!("{stack}-{id}");
11 DnsName::try_new(name).map(DnsName::into_inner)
12}
13
14#[cfg(test)]
15mod tests {
16 use super::*;
17
18 #[test]
19 fn typical_stack_name_is_valid() {
20 let name = compose_instance_name("hello").expect("hello + uuid");
21 assert!(name.starts_with("hello-"));
22 assert!(DnsName::try_new(&name).is_ok());
23 }
24
25 #[test]
26 fn uuid_segment_matches_hyphenated_form() {
27 let name = compose_instance_name("atto").expect("atto + uuid");
28 let Some((stack, uuid)) = name.split_once('-') else {
29 panic!("expected stack-uuid form, got {name:?}");
30 };
31 assert_eq!(stack, "atto");
32 let parts: Vec<_> = uuid.split('-').collect();
33 assert_eq!(parts.len(), 5);
34 assert_eq!(parts[0].len(), 8);
35 assert_eq!(parts[1].len(), 4);
36 assert_eq!(parts[2].len(), 4);
37 assert_eq!(parts[3].len(), 4);
38 assert_eq!(parts[4].len(), 12);
39 }
40
41 #[test]
42 fn overlong_stack_name_rejected() {
43 let stack = "a".repeat(27);
44 let err = compose_instance_name(&stack).expect_err("stack name too long for uuid suffix");
45 assert!(matches!(err, TypeError::InvalidDnsName { .. }));
46 }
47}