unicount_lib/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use {clap::ValueEnum, unicode_segmentation::UnicodeSegmentation};
4
5fn split(s: &str) -> Vec<String> {
6    UnicodeSegmentation::graphemes(s, true)
7        .map(|x| x.to_string())
8        .collect()
9}
10
11pub struct Counter {
12    current: usize,
13    alphabet: Vec<String>,
14}
15
16impl Counter {
17    pub fn new(alphabet: &str, start: usize) -> Counter {
18        Counter {
19            current: start,
20            alphabet: split(alphabet),
21        }
22    }
23
24    fn get(&self, x: usize) -> String {
25        let length = self.alphabet.len();
26        let d = x / length;
27        let r = x % length;
28        let t = self.alphabet[r].clone();
29        if d == 0 {
30            t
31        } else {
32            format!("{}{t}", self.get(d - 1))
33        }
34    }
35}
36
37impl std::iter::Iterator for Counter {
38    type Item = String;
39
40    fn next(&mut self) -> Option<Self::Item> {
41        let r = self.to_string();
42        self.current += 1;
43        Some(r)
44    }
45}
46
47impl std::fmt::Display for Counter {
48    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
49        write!(f, "{}", self.get(self.current))
50    }
51}
52
53#[derive(Clone, ValueEnum)]
54pub enum Kind {
55    EnglishUpper,
56    EnglishLower,
57}
58
59impl Kind {
60    pub fn counter(&self, start: usize) -> Counter {
61        match self {
62            Kind::EnglishUpper => Counter::new("ABCDEFGHIJKLMNOPQRSTUVWXYZ", start),
63            Kind::EnglishLower => Counter::new("abcdefghijklmnopqrstuvwxyz", start),
64        }
65    }
66}