1#![doc = include_str!("../README.md")]
2
3pub struct AlphaCounter {
4 number: usize,
5 alphabet: Vec<char>,
6 length: usize,
7}
8
9impl AlphaCounter {
10 #[must_use]
11 pub fn lower(number: usize) -> AlphaCounter {
12 AlphaCounter::custom(number, "abcdefghijklmnopqrstuvwxyz")
13 }
14
15 #[must_use]
16 pub fn upper(number: usize) -> AlphaCounter {
17 AlphaCounter::custom(number, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
18 }
19
20 #[must_use]
21 pub fn custom(number: usize, alphabet: &str) -> AlphaCounter {
22 let alphabet: Vec<char> = alphabet.chars().collect();
23 let length = alphabet.len();
24 AlphaCounter {
25 number,
26 alphabet,
27 length,
28 }
29 }
30
31 #[must_use]
32 pub fn recurse(&self, x: usize) -> String {
33 let d = x / self.length;
34 let r = x % self.length;
35 let t = self.alphabet[r];
36 if d == 0 {
37 format!("{t}")
38 } else {
39 format!("{}{t}", self.recurse(d - 1))
40 }
41 }
42}
43
44impl core::iter::Iterator for AlphaCounter {
45 type Item = String;
46
47 fn next(&mut self) -> Option<Self::Item> {
48 let r = self.to_string();
49 self.number += 1;
50 Some(r)
51 }
52}
53
54impl std::fmt::Display for AlphaCounter {
55 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
56 write!(f, "{}", self.recurse(self.number))
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn lower() {
66 assert_eq!(
67 AlphaCounter::lower(0).take(30).collect::<Vec<String>>(),
68 vec![
69 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p",
70 "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "aa", "ab", "ac", "ad"
71 ],
72 );
73 }
74
75 #[test]
76 fn upper() {
77 assert_eq!(
78 AlphaCounter::upper(0).take(30).collect::<Vec<String>>(),
79 vec![
80 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P",
81 "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD"
82 ],
83 );
84 }
85
86 #[test]
87 fn custom() {
88 assert_eq!(
89 AlphaCounter::custom(0, "abc")
90 .take(30)
91 .collect::<Vec<String>>(),
92 vec![
93 "a", "b", "c", "aa", "ab", "ac", "ba", "bb", "bc", "ca", "cb", "cc", "aaa", "aab",
94 "aac", "aba", "abb", "abc", "aca", "acb", "acc", "baa", "bab", "bac", "bba", "bbb",
95 "bbc", "bca", "bcb", "bcc"
96 ],
97 );
98 }
99}