alpha_counter/
lib.rs

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}