1//! Household names for the harness: a new one for every empty hub, never repeating across runs (the 2//! hosts keep state between runs). 3 4use std::cell::Cell; 5use std::time::{SystemTime, UNIX_EPOCH}; 6 7pub struct Households { 8 run: String, 9 n: Cell<u64>, 10} 11 12impl Households { 13 pub fn new(label: &str) -> Self { 14 let ms = SystemTime::now().duration_since(UNIX_EPOCH).map_or(0, |d| d.as_millis()); 15 Self { run: format!("{label}-{ms:x}"), n: Cell::new(0) } 16 } 17 18 /// A household nobody has used. 19 pub fn next(&self) -> String { 20 self.n.set(self.n.get() + 1); 21 format!("{}-{}", self.run, self.n.get()) 22 } 23} 24 25#[cfg(test)] 26mod tests { 27 use super::*; 28 29 #[test] 30 fn a_name_is_a_household_id_and_never_repeats() { 31 let h = Households::new("celld"); 32 let (a, b) = (h.next(), h.next()); 33 assert_ne!(a, b); 34 for id in [&a, &b] { 35 assert!(id.len() <= 63 && id.bytes().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == b'-'), "{id}"); 36 assert!(!id.starts_with('-') && !id.ends_with('-')); 37 } 38 } 39}