Skip to main content

everruns_core/
resource_names.rs

1//! Shared helpers for naming external resources created from user-visible titles.
2
3use rand::RngExt;
4
5const SUFFIX_ALPHABET: &[u8] = b"abcdefghijklmnopqrstuvwxyz0123456789";
6const SUFFIX_LEN: usize = 6;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct UniqueResourceName {
10    pub requested_name: String,
11    pub canonical_name: String,
12}
13
14pub fn unique_resource_name(requested_name: &str) -> UniqueResourceName {
15    let requested_name = requested_name.trim().to_string();
16    let base_name = requested_name.trim_end_matches('-');
17    let mut rng = rand::rng();
18    let suffix: String = (0..SUFFIX_LEN)
19        .map(|_| {
20            let index = rng.random_range(0..SUFFIX_ALPHABET.len());
21            SUFFIX_ALPHABET[index] as char
22        })
23        .collect();
24    let canonical_name = if base_name.is_empty() {
25        suffix
26    } else {
27        format!("{base_name}-{suffix}")
28    };
29
30    UniqueResourceName {
31        requested_name,
32        canonical_name,
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn unique_resource_name_appends_lowercase_alphanumeric_suffix() {
42        let name = unique_resource_name("sandbox-name");
43        let suffix = name
44            .canonical_name
45            .strip_prefix("sandbox-name-")
46            .expect("suffix should be appended");
47
48        assert_eq!(name.requested_name, "sandbox-name");
49        assert_eq!(suffix.len(), 6);
50        assert!(
51            suffix
52                .chars()
53                .all(|ch| ch.is_ascii_lowercase() || ch.is_ascii_digit())
54        );
55    }
56
57    #[test]
58    fn unique_resource_name_trims_input_and_trailing_dash() {
59        let name = unique_resource_name("  sandbox-name-  ");
60
61        assert_eq!(name.requested_name, "sandbox-name-");
62        assert!(name.canonical_name.starts_with("sandbox-name-"));
63        assert!(!name.canonical_name.starts_with("sandbox-name--"));
64    }
65}