use crate::base::{set_low_numwords, set_mid_numwords, Cards, Lang, N2WError, Result};
use crate::currency::CurrencyForms;
use crate::floatpath::FloatValue;
use num_bigint::BigInt;
use num_traits::{One, Signed, Zero};
use std::collections::HashMap;
const LOW_NUMWORDS: [&str; 100] = [
"\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc7}\u{0cb3}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc8}\u{0ca6}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0ca4}\u{0cc6}\u{0cc2}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc7}\u{0cb3}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc8}\u{0ca6}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cc2}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc7}\u{0cb3}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc8}\u{0ca6}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0c8e}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc7}\u{0cb3}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc8}\u{0ca6}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0c85}\u{0cb0}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc7}\u{0cb3}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc8}\u{0ca6}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0c90}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc7}\u{0cb3}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cd6}\u{0ca6}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0c8e}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc6}\u{0cc2}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0ca8}\u{0cb2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0c92}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0c8e}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0c8f}\u{0cb3}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0c86}\u{0cb0}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0c90}\u{0ca6}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0c8e}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0c92}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb5}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0c92}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0c8e}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0c8f}\u{0cb3}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0c86}\u{0cb0}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0c90}\u{0ca6}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0c8e}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0ccd}\u{0020}\u{0c92}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0c87}\u{0caa}\u{0ccd}\u{0caa}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0cb9}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cca}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0cb9}\u{0ca6}\u{0cbf}\u{0ca8}\u{0cc6}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0cb9}\u{0ca6}\u{0cbf}\u{0ca8}\u{0cc6}\u{0cd5}\u{0cb3}\u{0cc1}", "\u{0cb9}\u{0ca6}\u{0cbf}\u{0ca8}\u{0cbe}\u{0cb0}\u{0cc1}", "\u{0cb9}\u{0ca6}\u{0cbf}\u{0ca8}\u{0cc6}\u{0cd6}\u{0ca6}\u{0cc1}", "\u{0cb9}\u{0ca6}\u{0cbf}\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0cb9}\u{0ca6}\u{0cbf}\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0cb9}\u{0ca8}\u{0ccd}\u{0ca8}\u{0cc6}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0cb9}\u{0ca8}\u{0ccd}\u{0ca8}\u{0cc6}\u{0cc2}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0cb9}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c92}\u{0c82}\u{0cac}\u{0ca4}\u{0ccd}\u{0ca4}\u{0cc1}", "\u{0c8e}\u{0c82}\u{0c9f}\u{0cc1}", "\u{0c8f}\u{0cb3}\u{0cc1}", "\u{0c86}\u{0cb0}\u{0cc1}", "\u{0c90}\u{0ca6}\u{0cc1}", "\u{0ca8}\u{0cbe}\u{0cb2}\u{0ccd}\u{0c95}\u{0cc1}", "\u{0cae}\u{0cc2}\u{0cb0}\u{0cc1}", "\u{0c8e}\u{0cb0}\u{0ca1}\u{0cc1}", "\u{0c92}\u{0c82}\u{0ca6}\u{0cc1}", "\u{0cb8}\u{0cca}\u{0ca8}\u{0ccd}\u{0ca8}\u{0cc6}", ];
const MODIFIERS: [&str; 15] = [
"\u{0ccd}", "\u{0cbe}", "\u{0cbf}", "\u{0cbf}\u{0cd5}", "\u{0cc0}", "\u{0cc1}", "\u{0cc2}", "\u{0cc3}", "\u{0cc6}", "\u{0cc7}", "\u{0cc8}", "\u{0cca}", "\u{0ccb}", "\u{0ccc}", "\u{0cd5}", ];
const ORDINAL_SUFFIX: &str = "\u{0ca8}\u{0cc7}"; const GENITIVE: &str = "\u{0ca6}"; const POINTWORD: &str = "\u{0cac}\u{0cbf}\u{0c82}\u{0ca6}\u{0cc1}"; const HUNDRED: &str = "\u{0ca8}\u{0cc2}\u{0cb0}\u{0cc1}"; const THOUSAND: &str = "\u{0cb8}\u{0cbe}\u{0cb5}\u{0cbf}\u{0cb0}"; const LAKH: &str = "\u{0cb2}\u{0c95}\u{0ccd}\u{0cb7}"; const CRORE: &str = "\u{0c95}\u{0cca}\u{0cd5}\u{0c9f}\u{0cbf}";
const CURRENCY_FORMS: [(&str, &[&str], &[&str]); 39] = [
("AED", &["dirham", "dirhams"], &["fils", "fils"]),
("AUD", &["dollar", "dollars"], &["cent", "cents"]),
("BHD", &["dinar", "dinars"], &["fils", "fils"]),
("BRL", &["real", "reais"], &["cent", "cents"]),
("BYN", &["rouble", "roubles"], &["kopek", "kopeks"]),
("CAD", &["dollar", "dollars"], &["cent", "cents"]),
("CHF", &["franc", "francs"], &["rappen", "rappen"]),
("CNY", &["yuan", "yuan"], &["fen", "fen"]),
("EEK", &["kroon", "kroons"], &["sent", "senti"]),
("EUR", &["euro", "euros"], &["cent", "cents"]),
("GBP", &["pound", "pounds"], &["penny", "pence"]),
("HKD", &["dollar", "dollars"], &["cent", "cents"]),
(
"HUF",
&["forint", "forint"],
&["fill\u{00e9}r", "fill\u{00e9}r"],
), ("INR", &["rupee", "rupees"], &["paisa", "paise"]),
("IQD", &["dinar", "dinars"], &["fils", "fils"]),
("ISK", &["kr\u{00f3}na", "kr\u{00f3}nur"], &["aur", "aurar"]), ("JOD", &["dinar", "dinars"], &["fils", "fils"]),
("JPY", &["yen", "yen"], &["sen", "sen"]),
("KRW", &["won", "won"], &["jeon", "jeon"]),
("KWD", &["dinar", "dinars"], &["fils", "fils"]),
("LTL", &["litas", "litas"], &["cent", "cents"]),
("LVL", &["lat", "lats"], &["santim", "santims"]),
("LYD", &["dinar", "dinars"], &["dirham", "dirhams"]),
("MXN", &["peso", "pesos"], &["cent", "cents"]),
("NGN", &["naira", "naira"], &["kobo", "kobo"]),
("NOK", &["krone", "kroner"], &["\u{00f8}re", "\u{00f8}re"]), ("NZD", &["dollar", "dollars"], &["cent", "cents"]),
("OMR", &["rial", "rials"], &["baisa", "baisa"]),
("PLN", &["zloty", "zlotys", "zlotu"], &["grosz", "groszy"]),
("QAR", &["riyal", "riyals"], &["dirham", "dirhams"]),
(
"RON",
&["leu", "lei", "de lei"],
&["ban", "bani", "de bani"],
),
("RUB", &["rouble", "roubles"], &["kopek", "kopeks"]),
("SAR", &["riyal", "riyals"], &["halalah", "halalas"]),
("SEK", &["krona", "kronor"], &["\u{00f6}re", "\u{00f6}re"]), ("SGD", &["dollar", "dollars"], &["cent", "cents"]),
("TND", &["dinar", "dinars"], &["millime", "millimes"]),
("USD", &["dollar", "dollars"], &["cent", "cents"]),
("UZS", &["sum", "sums"], &["tiyin", "tiyins"]),
("ZAR", &["rand", "rand"], &["cent", "cents"]),
];
const CURRENCY_ADJECTIVES: [(&str, &str); 16] = [
("AUD", "Australian"),
("BYN", "Belarusian"),
("CAD", "Canadian"),
("EEK", "Estonian"),
("HUF", "Hungarian"),
("INR", "Indian"),
("ISK", "\u{00ed}slenskar"), ("JPY", "Japanese"),
("KRW", "Korean"),
("MXN", "Mexican"),
("NOK", "Norwegian"),
("RON", "Romanian"),
("RUB", "Russian"),
("SAR", "Saudi"),
("USD", "US"),
("UZS", "Uzbekistan"),
];
fn ends_with_modifier(s: &str) -> bool {
match s.chars().next_back() {
Some(c) => {
let mut buf = [0u8; 4];
let last: &str = c.encode_utf8(&mut buf);
MODIFIERS.contains(&last)
}
None => false,
}
}
fn strip_last_char(s: &str) -> String {
let mut it = s.chars();
it.next_back();
it.as_str().to_string()
}
pub struct LangKn {
cards: Cards,
maxval: BigInt,
currency_forms: HashMap<&'static str, CurrencyForms>,
}
impl Default for LangKn {
fn default() -> Self {
Self::new()
}
}
impl LangKn {
pub fn new() -> Self {
let mut cards = Cards::new();
for (n, word) in [(7u32, CRORE), (5, LAKH), (3, THOUSAND)] {
cards.insert(BigInt::from(10u8).pow(n), word);
}
set_mid_numwords(&mut cards, &[(100, HUNDRED)]);
set_low_numwords(&mut cards, &LOW_NUMWORDS);
let maxval = cards.highest().cloned().unwrap_or_else(BigInt::zero) * BigInt::from(1000);
let currency_forms = CURRENCY_FORMS
.iter()
.map(|(code, unit, subunit)| (*code, CurrencyForms::new(unit, subunit)))
.collect();
LangKn {
cards,
maxval,
currency_forms,
}
}
fn verify_ordinal(&self, value: &BigInt) -> Result<()> {
if value.is_negative() {
return Err(N2WError::Type(format!(
"Cannot treat negative num {} as ordinal.",
value
)));
}
Ok(())
}
}
impl Lang for LangKn {
fn default_currency(&self) -> &str {
"EUR"
}
fn default_separator(&self) -> &str {
","
}
fn cards(&self) -> &Cards {
&self.cards
}
fn maxval(&self) -> &BigInt {
&self.maxval
}
fn pointword(&self) -> &str {
"ಬಿಂದು"
}
fn merge(&self, l: (&str, &BigInt), r: (&str, &BigInt)) -> (String, BigInt) {
let (ltext, lnum) = l;
let (rtext, rnum) = r;
let hundred = BigInt::from(100);
if lnum.is_one() && rnum < &hundred {
(rtext.to_string(), rnum.clone())
} else if &hundred > lnum && lnum > rnum {
(format!("{}-{}", ltext, rtext), lnum + rnum)
} else if lnum >= &hundred && &hundred > rnum {
if ends_with_modifier(ltext) {
(format!("{} {}", strip_last_char(ltext), rtext), lnum + rnum)
} else {
(format!("{}{} {}", ltext, GENITIVE, rtext), lnum + rnum)
}
} else if rnum > lnum {
(format!("{} {}", ltext, rtext), lnum * rnum)
} else {
(format!("{} {}", ltext, rtext), lnum + rnum)
}
}
fn to_ordinal(&self, value: &BigInt) -> Result<String> {
self.verify_ordinal(value)?;
let outwords = self.to_cardinal(value)?;
let stem = if ends_with_modifier(&outwords) {
strip_last_char(&outwords)
} else {
outwords
};
Ok(format!("{}{}", stem, ORDINAL_SUFFIX))
}
fn to_ordinal_num(&self, value: &BigInt) -> Result<String> {
self.verify_ordinal(value)?;
Ok(format!("{}{}", value, self.to_ordinal(value)?))
}
fn ordinal_float_entry(&self, value: &FloatValue) -> Result<String> {
let i = verify_ordinal_float(value, &ordinal_float_repr(value))?;
self.to_ordinal(&i)
}
fn ordinal_num_float_entry(&self, value: &FloatValue, repr_str: &str) -> Result<String> {
let i = verify_ordinal_float(value, repr_str)?;
Ok(format!("{}{}", repr_str, self.to_ordinal(&i)?))
}
fn lang_name(&self) -> &str {
"Num2Word_KN"
}
fn currency_forms(&self, code: &str) -> Option<&CurrencyForms> {
self.currency_forms.get(code)
}
fn currency_adjective(&self, code: &str) -> Option<&str> {
CURRENCY_ADJECTIVES
.iter()
.find(|(k, _)| *k == code)
.map(|(_, v)| *v)
}
fn pluralize(&self, n: &BigInt, forms: &[String]) -> Result<String> {
let form = if n.is_one() { 0 } else { 1 };
forms
.get(form)
.cloned()
.ok_or_else(|| N2WError::Index("tuple index out of range".into()))
}
}
fn verify_ordinal_float(value: &FloatValue, repr: &str) -> Result<BigInt> {
match value.as_whole_int() {
None => Err(N2WError::Type(format!(
"Cannot treat float {} as ordinal.",
repr
))),
Some(i) if i.is_negative() => Err(N2WError::Type(format!(
"Cannot treat negative num {} as ordinal.",
repr
))),
Some(i) => Ok(i),
}
}
fn ordinal_float_repr(value: &FloatValue) -> String {
match value {
FloatValue::Decimal { value, .. } => crate::strnum::python_decimal_str(value),
FloatValue::Float { value, .. } => {
if value.is_finite() && value.fract() == 0.0 && value.abs() < 1e16 {
format!("{:.1}", value)
} else {
value.to_string()
}
}
}
}