pub const ID_LEN: usize = 64;
pub const ID_LEN_NAME: usize = ID_LEN + 1;
pub const ID_COUNT: usize = 60;
static NUMBERED_IDENTS: [&str; ID_COUNT] = [
"_0", "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9", "_10", "_11", "_12", "_13", "_14", "_15", "_16",
"_17", "_18", "_19", "_20", "_21", "_22", "_23", "_24", "_25", "_26", "_27", "_28", "_29", "_30", "_31",
"_32", "_33", "_34", "_35", "_36", "_37", "_38", "_39", "_40", "_41", "_42", "_43", "_44", "_45", "_46",
"_47", "_48", "_49", "_50", "_51", "_52", "_53", "_54", "_55", "_56", "_57", "_58", "_59",
];
pub fn numbered_ident(id: usize) -> Option<&'static str> {
NUMBERED_IDENTS.get(id).copied()
}
pub fn ident_number(ident: &str) -> Option<usize> {
let id = ident.strip_prefix("_")?.parse::<usize>().ok()?;
(numbered_ident(id) == Some(ident)).then_some(id)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn numbered_idents_agree() {
for id in 0..ID_COUNT {
let ident = numbered_ident(id).expect("every number below the count has a name");
assert_eq!(ident, format!("_{id}"));
assert_eq!(ident_number(ident), Some(id));
}
assert_eq!(numbered_ident(ID_COUNT), None);
assert_eq!(ident_number(&format!("_{ID_COUNT}")), None);
assert_eq!(ident_number("name"), None);
assert_eq!(ident_number("_"), None);
assert_eq!(ident_number("_x"), None);
}
#[test]
fn only_the_canonical_form_is_numbered() {
assert_eq!(ident_number("_0"), Some(0));
assert_eq!(ident_number("_59"), Some(59));
assert_eq!(ident_number("_00"), None);
assert_eq!(ident_number("_07"), None);
assert_eq!(ident_number("_007"), None);
assert_eq!(ident_number("_+7"), None);
}
}