use crate::ParseError;
static NAMES_UPTO_TWENTY: [&str; 20] = [
"", "one", "two", "three", "four", "five", "six", "seven", "eight",
"nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
"sixteen", "seventeen", "eighteen", "nineteen"
];
static TENS_NAMES: [&str; 10] = [
"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy",
"eighty", "ninety"
];
static LATIN_BASE_PREFIXES: [&str; 10] = [
"n", "m", "b", "tr", "quadr", "quint", "sext", "sept", "oct", "non"
];
static LATIN_UNIT_PREFIXES: [&str; 10] = [
"", "un", "duo", "tre", "quattuor", "quinqua", "se", "septe", "octo",
"nove"
];
static LATIN_TENS_PREFIXES: [&str; 10] = [
"", "deci", "viginti", "triginta", "quadraginta", "quinquaginta",
"sexaginta", "septuaginta", "octoginta", "nonaginta"
];
static LATIN_HUNDREDS_PREFIXES: [&str; 10] = [
"", "centi", "ducenti", "trecenti", "quadringenti", "quingenti",
"sescenti", "septingenti", "octingenti", "nongenti"
];
pub fn is_all_digits(s: &str) -> bool {
s.chars().all(|c| c.is_digit(10))
}
pub fn num_from_slice(digits: &str, index: usize, ndigits: usize) -> usize {
digits.get(index..index+ndigits).unwrap().parse::<usize>().unwrap()
}
pub fn latin_prefix(num: usize) -> Result<String, ParseError> {
if num >= 1000 { return Err(ParseError::InputTooLarge); }
if num < 10 {
return Ok(String::from(LATIN_BASE_PREFIXES[num]));
}
let hs = num / 100; let ts = num % 100 / 10; let us = num % 10;
let mut prefix = String::from(LATIN_UNIT_PREFIXES[us]);
if ts > 0 {
match (us, ts) {
(3, 2..=5) | (3, 8) => prefix.push('s'), (6, 2..=5) => prefix.push('s'), (6, 8) => prefix.push('x'), (7, 1) | (7, 3..=7) => prefix.push('n'), (7, 2) | (7, 8) => prefix.push('m'), (9, 1) | (9, 3..=7) => prefix.push('n'), (9, 2) | (9, 8) => prefix.push('m'), _ => (),
}
prefix.push_str(LATIN_TENS_PREFIXES[ts]);
prefix.push_str(LATIN_HUNDREDS_PREFIXES[hs]);
}
else {
match (us, hs) {
(3, 1) | (3, 3..=5) | (3, 8) => prefix.push('s'), (6, 1) | (6, 8) => prefix.push('x'), (6, 3..=5) => prefix.push('s'), (7, 1..=7) => prefix.push('n'), (7, 8) => prefix.push('m'), (9, 1..=7) => prefix.push('n'), (9, 8) => prefix.push('m'), _ => (),
}
prefix.push_str(LATIN_HUNDREDS_PREFIXES[hs]);
}
prefix.pop();
Ok(prefix)
}
fn name_hundreds(tens: usize, units: usize) -> String {
let mut output = String::from(TENS_NAMES[tens]);
if output.is_empty() {
output.push_str(NAMES_UPTO_TWENTY[(10*tens)+units]);
}
else if units > 0 {
output.push(' ');
output.push_str(NAMES_UPTO_TWENTY[units]);
}
output
}
pub fn myriad_number(num: usize) -> Result<String, ParseError> {
if num >= 10000 {
return Err(ParseError::InternalError);
}
let ms = num / 1000; let hs = num % 1000 / 100; let ts = num % 100 / 10; let us = num % 10;
let mut output = name_hundreds(ms, hs);
let append = name_hundreds(ts, us);
if !output.is_empty() { output.push_str(" hundred "); }
if !append.is_empty() {
output.push_str(append.as_str());
output.push(' ');
}
output.pop(); Ok(output)
}