use std::collections::HashSet;
use tracing::debug;
static SUFFIXES: &[&str] = &[
"-dev",
"-staging",
"-test",
"-prod",
"-old",
"-new",
"-internal",
"-v2",
"2",
"1",
];
static PREFIXES: &[&str] = &["dev-", "staging-", "test-", "prod-", "api-"];
pub fn generate_permutations(discovered_labels: &HashSet<String>) -> HashSet<String> {
let mut permutations = HashSet::new();
for label in discovered_labels {
for suffix in SUFFIXES {
let permuted = format!("{label}{suffix}");
if !discovered_labels.contains(&permuted) {
permutations.insert(permuted);
}
}
for prefix in PREFIXES {
let permuted = format!("{prefix}{label}");
if !discovered_labels.contains(&permuted) {
permutations.insert(permuted);
}
}
}
debug!(
"Generated {} permutations from {} labels",
permutations.len(),
discovered_labels.len()
);
permutations
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic_permutation() {
let discovered: HashSet<String> = vec!["www".to_string()].into_iter().collect();
let result = generate_permutations(&discovered);
assert!(result.contains("www-dev"));
assert!(result.contains("www-staging"));
assert!(result.contains("www-test"));
assert!(result.contains("dev-www"));
assert!(result.contains("staging-www"));
assert!(!result.contains("www")); }
#[test]
fn empty_input() {
let discovered: HashSet<String> = HashSet::new();
let result = generate_permutations(&discovered);
assert!(result.is_empty());
}
#[test]
fn excludes_already_discovered() {
let discovered: HashSet<String> = vec!["www".to_string(), "www-dev".to_string()].into_iter().collect();
let result = generate_permutations(&discovered);
assert!(!result.contains("www-dev"));
assert!(result.contains("www-staging"));
}
#[test]
fn multiple_labels() {
let discovered: HashSet<String> = vec!["api".to_string(), "mail".to_string()].into_iter().collect();
let result = generate_permutations(&discovered);
assert!(result.contains("api-dev"));
assert!(result.contains("mail-dev"));
assert!(result.contains("dev-api"));
assert!(result.contains("dev-mail"));
}
}