fn count_to_letter_code(mut count: usize) -> String {
let mut letters = Vec::new();
+ // +2 rather than +1 to account for the _ at the end
+ let length = count.checked_ilog(26).unwrap_or(0) as usize + 2;
+
+ letters.reserve(length);
+
loop {
- let letter_idx = (count % 26) as u32;
- letters.push(char::from_u32('A' as u32 + letter_idx).unwrap());
+ let letter_idx = (count % 26) as u8;
+ letters.push(b'A' + letter_idx);
count /= 26;
if count == 0 {
}
}
- letters.into_iter().chain("_".chars()).rev().collect()
+ letters.push(b'_');
+
+ debug_assert_eq!(length, letters.len());
+
+ letters.reverse();
+
+ // Safety: we only push ascii chars A-Z and _
+ // an ascii only byte sequence is always valid utf-8
+ unsafe { String::from_utf8_unchecked(letters) }
}
impl Term {
}
}
}
+
+#[test]
+fn test_count_to_letter_code() {
+ for idx in 0..1000 {
+ // ensure the debug assert doesn't trigger
+ count_to_letter_code(idx);
+ }
+}