1use cerno_types::MAX_OPTIONS;
4
5const ALPHABET: [&str; MAX_OPTIONS] = [
15 "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
16 "T",
17];
18
19pub fn label(index: usize) -> Option<&'static str> {
21 ALPHABET.get(index).copied()
22}
23
24pub fn labels(count: usize) -> Vec<&'static str> {
26 ALPHABET.iter().take(count).copied().collect()
27}
28
29pub fn matches(token: &str, label: &str) -> bool {
35 let token = token.trim();
36 token.len() == label.len() && token.eq_ignore_ascii_case(label)
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn labels_start_at_a_and_run_in_order() {
45 assert_eq!(labels(3), vec!["A", "B", "C"]);
46 assert_eq!(label(0), Some("A"));
47 assert_eq!(label(19), Some("T"));
48 }
49
50 #[test]
52 fn the_alphabet_stops_at_the_host_ceiling() {
53 assert_eq!(ALPHABET.len(), MAX_OPTIONS);
54 assert_eq!(label(MAX_OPTIONS), None);
55 assert_eq!(labels(99).len(), MAX_OPTIONS);
56 }
57
58 #[test]
59 fn matching_tolerates_leading_space_and_lower_case() {
60 assert!(matches("A", "A"));
61 assert!(matches(" A", "A"));
62 assert!(matches("a", "A"));
63 assert!(matches(" a ", "A"));
64 }
65
66 #[test]
68 fn matching_rejects_longer_tokens() {
69 assert!(!matches("AB", "A"));
70 assert!(!matches("A)", "A"));
71 assert!(!matches("B", "A"));
72 assert!(!matches("", "A"));
73 }
74}