use super::*;
pub fn int_to_string(i: u64) -> Result<String, SequenceError> {
let (quot, rem) = (i / (LETTERS + 1), i % (LETTERS + 1));
if quot == 0 {
return Ok(String::from(int_to_char(rem as u32)?))
}
return Ok(
format!(
"{}{}",
int_to_string(quot - 1)?,
String::from(int_to_char(rem as u32)?),
)
)
}
pub fn int_to_char(i: u32) -> Result<char, SequenceError> {
const ASCII_A_OFFSET: u32 = 'A' as u32;
if i > LETTERS as u32 {
return Err(SequenceError::NotAsciiCharacter)
}
let letter = std::char::from_u32(i + ASCII_A_OFFSET)
.unwrap();
Ok(letter)
}
pub fn char_to_int(c: char) -> Result<u8, SequenceError> {
if c.is_ascii_alphabetic() {
Ok(c.to_ascii_uppercase() as u8 - 'A' as u8)
}
else {
Err(SequenceError::InvalidCharacter(c))
}
}
pub fn string_to_int(s: &str) -> Result<u64, SequenceError> {
let mut max: u64 = 0;
for (i,val) in s.chars().rev().enumerate() {
let ord = char_to_int(val)? as u64;
max += (1+ord) * 26u64.pow(i as u32);
}
Ok(max - 1)
}
#[cfg(test)]
mod test{
use super::*;
mod char {
use super::*;
#[test]
fn simple() {
for c in 'A'..'Z' {
assert_eq!(int_to_char(c as u32 - 'A' as u32).unwrap(), c);
}
assert!(
matches!(
int_to_char('Z' as u32 + 1).unwrap_err(),
SequenceError::NotAsciiCharacter
)
);
}
}
}