pub const fn check_char(c: char) -> bool {
(c as u32) < 127 && c as u32 > 31
}
pub fn valid_text(text: impl AsRef<str>) -> bool {
text.as_ref().chars().all(check_char)
}
pub fn valid_identifier(text: impl AsRef<str>) -> bool {
text.as_ref().chars().all(check_char)
}
pub fn prepare_identifier(text: impl AsRef<str>) -> Option<String> {
let text = text.as_ref();
(valid_identifier(text) && !text.trim().is_empty()).then(|| text.trim().to_ascii_uppercase())
}
const ALPHABET: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#[allow(clippy::unwrap_used)]
pub fn number_to_base26(mut num: usize) -> String {
let mut output = vec![ALPHABET.chars().nth(num % 26).unwrap()];
num /= 26;
while num != 0 {
output.push(ALPHABET.chars().nth(num % 26).unwrap());
num /= 26;
}
output.iter().rev().collect::<String>()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn correct_examples() {
assert!(check_char('a'));
assert!(check_char('9'));
assert!(check_char('*'));
assert!(check_char('@'));
assert!(check_char('O'));
assert!(valid_text("ResidueName"));
assert!(valid_text("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`-=[]\\;',./~!@#$%^&*()_+{}|:\"<>? "));
}
#[test]
fn incorrect_examples() {
assert!(!check_char('̊'));
assert!(!check_char('∞'));
assert!(!check_char('👍'));
assert!(!check_char('ÿ'));
assert!(!check_char('\u{0}'));
assert!(!valid_text("ResidueName∞"));
assert!(!valid_text("Escape\u{0}"));
}
#[test]
fn number_to_base26_test() {
assert_eq!(number_to_base26(26), "BA");
assert_eq!(number_to_base26(0), "A");
assert_eq!(number_to_base26(234), "JA");
assert_eq!(number_to_base26(25), "Z");
assert_eq!(number_to_base26(457), "RP");
assert_eq!(number_to_base26(15250), "WOO");
assert_eq!(number_to_base26(396514), "WOOO");
}
}