use std::{collections::HashMap, sync::OnceLock};
use bitcode::{Decode, Encode};
#[derive(Encode, Decode)]
pub struct Booleans {
pub r#true: String,
pub r#false: String,
}
#[derive(Encode, Decode)]
pub struct Errors {
pub r#ref: String,
pub name: String,
pub value: String,
pub div: String,
pub na: String,
pub num: String,
pub nimpl: String,
pub spill: String,
pub calc: String,
pub circ: String,
pub error: String,
pub null: String,
}
#[derive(Encode, Decode)]
pub struct Functions {
pub and: String,
pub r#false: String,
pub r#if: String,
pub iferror: String,
pub ifna: String,
pub ifs: String,
pub not: String,
pub or: String,
pub switch: String,
pub r#true: String,
pub xor: String,
pub log: String,
pub log10: String,
pub ln: String,
pub sin: String,
pub cos: String,
pub tan: String,
pub asin: String,
pub acos: String,
pub atan: String,
pub sinh: String,
pub cosh: String,
pub tanh: String,
pub asinh: String,
pub acosh: String,
pub atanh: String,
pub acot: String,
pub acoth: String,
pub cot: String,
pub coth: String,
pub csc: String,
pub csch: String,
pub sec: String,
pub sech: String,
pub abs: String,
pub pi: String,
pub sqrt: String,
pub sqrtpi: String,
pub atan2: String,
pub power: String,
pub max: String,
pub min: String,
pub product: String,
pub rand: String,
pub randbetween: String,
pub round: String,
pub rounddown: String,
pub roundup: String,
pub sum: String,
pub sumif: String,
pub sumifs: String,
pub choose: String,
pub column: String,
pub columns: String,
pub index: String,
pub indirect: String,
pub hlookup: String,
pub lookup: String,
pub r#match: String,
pub offset: String,
pub row: String,
pub rows: String,
pub vlookup: String,
pub xlookup: String,
pub concatenate: String,
pub exact: String,
pub value: String,
pub t: String,
pub valuetotext: String,
pub concat: String,
pub find: String,
pub left: String,
pub len: String,
pub lower: String,
pub mid: String,
pub right: String,
pub search: String,
pub text: String,
pub trim: String,
pub unicode: String,
pub upper: String,
pub isnumber: String,
pub isnontext: String,
pub istext: String,
pub islogical: String,
pub isblank: String,
pub iserr: String,
pub iserror: String,
pub isna: String,
pub na: String,
pub isref: String,
pub isodd: String,
pub iseven: String,
pub errortype: String,
pub formulatext: String,
pub isformula: String,
pub r#type: String,
pub sheet: String,
pub average: String,
pub averagea: String,
pub avedev: String,
pub averageif: String,
pub averageifs: String,
pub count: String,
pub counta: String,
pub countblank: String,
pub countif: String,
pub countifs: String,
pub maxifs: String,
pub minifs: String,
pub geomean: String,
pub year: String,
pub day: String,
pub month: String,
pub eomonth: String,
pub date: String,
pub datedif: String,
pub datevalue: String,
pub edate: String,
pub networkdays: String,
pub networkdaysintl: String,
pub time: String,
pub timevalue: String,
pub hour: String,
pub minute: String,
pub second: String,
pub today: String,
pub now: String,
pub days: String,
pub days360: String,
pub weekday: String,
pub weeknum: String,
pub workday: String,
pub workdayintl: String,
pub yearfrac: String,
pub isoweeknum: String,
pub pmt: String,
pub pv: String,
pub rate: String,
pub nper: String,
pub fv: String,
pub ppmt: String,
pub ipmt: String,
pub npv: String,
pub mirr: String,
pub irr: String,
pub xirr: String,
pub xnpv: String,
pub rept: String,
pub textafter: String,
pub textbefore: String,
pub textjoin: String,
pub substitute: String,
pub ispmt: String,
pub rri: String,
pub sln: String,
pub syd: String,
pub nominal: String,
pub effect: String,
pub pduration: String,
pub tbillyield: String,
pub tbillprice: String,
pub tbilleq: String,
pub dollarde: String,
pub dollarfr: String,
pub ddb: String,
pub db: String,
pub cumprinc: String,
pub cumipmt: String,
pub besseli: String,
pub besselj: String,
pub besselk: String,
pub bessely: String,
pub erf: String,
pub erfprecise: String,
pub erfc: String,
pub erfcprecise: String,
pub bin2dec: String,
pub bin2hex: String,
pub bin2oct: String,
pub dec2bin: String,
pub dec2hex: String,
pub dec2oct: String,
pub hex2bin: String,
pub hex2dec: String,
pub hex2oct: String,
pub oct2bin: String,
pub oct2dec: String,
pub oct2hex: String,
pub bitand: String,
pub bitlshift: String,
pub bitor: String,
pub bitrshift: String,
pub bitxor: String,
pub complex: String,
pub imabs: String,
pub imaginary: String,
pub imargument: String,
pub imconjugate: String,
pub imcos: String,
pub imcosh: String,
pub imcot: String,
pub imcsc: String,
pub imcsch: String,
pub imdiv: String,
pub imexp: String,
pub imln: String,
pub imlog10: String,
pub imlog2: String,
pub impower: String,
pub improduct: String,
pub imreal: String,
pub imsec: String,
pub imsech: String,
pub imsin: String,
pub imsinh: String,
pub imsqrt: String,
pub imsub: String,
pub imsum: String,
pub imtan: String,
pub convert: String,
pub delta: String,
pub gestep: String,
pub subtotal: String,
pub exp: String,
pub fact: String,
pub factdouble: String,
pub sign: String,
pub radians: String,
pub degrees: String,
pub int: String,
pub even: String,
pub odd: String,
pub ceiling: String,
pub ceilingmath: String,
pub ceilingprecise: String,
pub floor: String,
pub floormath: String,
pub floorprecise: String,
pub isoceiling: String,
pub r#mod: String,
pub quotient: String,
pub mround: String,
pub trunc: String,
pub gcd: String,
pub lcm: String,
pub base: String,
pub decimal: String,
pub roman: String,
pub arabic: String,
pub combin: String,
pub combina: String,
pub sumsq: String,
pub n: String,
pub cell: String,
pub info: String,
pub sheets: String,
pub daverage: String,
pub dcount: String,
pub dget: String,
pub dmax: String,
pub dmin: String,
pub dsum: String,
pub dcounta: String,
pub dproduct: String,
pub dstdev: String,
pub dvar: String,
pub dvarp: String,
pub dstdevp: String,
pub betadist: String,
pub betainv: String,
pub binomdist: String,
pub binomdistrange: String,
pub binominv: String,
pub chisqdist: String,
pub chisqdistrt: String,
pub chisqinv: String,
pub chisqinvrt: String,
pub chisqtest: String,
pub confidencenorm: String,
pub confidencet: String,
pub covariancep: String,
pub covariances: String,
pub devsq: String,
pub expondist: String,
pub fdist: String,
pub fdistrt: String,
pub finv: String,
pub finvrt: String,
pub fisher: String,
pub fisherinv: String,
pub ftest: String,
pub gamma: String,
pub gammadist: String,
pub gammainv: String,
pub gammaln: String,
pub gammalnprecise: String,
pub hypgeomdist: String,
pub lognormdist: String,
pub lognorminv: String,
pub negbinomdist: String,
pub normdist: String,
pub norminv: String,
pub normsdist: String,
pub normsinv: String,
pub pearson: String,
pub phi: String,
pub poissondist: String,
pub standardize: String,
pub stdevp: String,
pub stdevs: String,
pub stdeva: String,
pub stdevpa: String,
pub tdist: String,
pub tdist2t: String,
pub tdistrt: String,
pub tinv: String,
pub tinv2t: String,
pub ttest: String,
pub varp: String,
pub vars: String,
pub varpa: String,
pub vara: String,
pub weibulldist: String,
pub ztest: String,
pub sumx2my2: String,
pub sumx2py2: String,
pub sumxmy2: String,
pub correl: String,
pub rsq: String,
pub intercept: String,
pub slope: String,
pub steyx: String,
pub gauss: String,
pub harmean: String,
pub kurt: String,
pub large: String,
pub maxa: String,
pub median: String,
pub mina: String,
pub rankavg: String,
pub rankeq: String,
pub skew: String,
pub skewp: String,
pub small: String,
}
#[derive(Encode, Decode)]
pub struct Language {
pub name: String,
pub code: String,
pub booleans: Booleans,
pub errors: Errors,
pub functions: Functions,
}
pub fn get_default_language() -> &'static Language {
#[allow(clippy::unwrap_used)]
get_language("en").unwrap()
}
static LANGUAGES: OnceLock<HashMap<String, Language>> = OnceLock::new();
#[allow(clippy::expect_used)]
fn get_languages() -> &'static HashMap<String, Language> {
LANGUAGES.get_or_init(|| {
bitcode::decode(include_bytes!("language.bin")).expect("Failed parsing language file")
})
}
pub fn get_language(id: &str) -> Result<&'static Language, String> {
get_languages()
.get(id)
.ok_or_else(|| format!("Language is not supported: '{id}'"))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_load_languages() {
let languages = get_languages();
assert!(!languages.is_empty());
for (code, language) in languages.iter() {
assert_eq!(code, &language.code);
}
}
}