diff --git a/CHANGELOG.md b/CHANGELOG.md index a8c7e71..62b4c81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # Changelog ## Next -- Add ambiguous unit resolution depending on context and user locale. `pound` can now become `GBP` or `lbs` -- Add currency symbols like `€` +- Add ambiguous unit resolution depending on context and user locale. +- Add ambiguous units like `pound` +- Add currency symbols like `€` and `kr` - Add `as` and `into` keywords for unit conversion - Fix some units not being simplified diff --git a/src/lexer.rs b/src/lexer.rs index c2352c6..e712b11 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -22,7 +22,7 @@ fn is_word_char_str(input: &str) -> bool { "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" => true, "Ω" | "Ω" | "µ" | "μ" | "ł" | "$" | "€" | "£" | "₹" | "₪" | "¥" | "₩" | "₱" | "฿" | "₺" - | "₴" | "₫" => true, + | "₴" | "₫" | "đ" | "Đ" | "č" => true, _ => false, } } @@ -649,14 +649,23 @@ fn lex_word(word: &str, lexer: &mut Lexer) -> Result<(), String> { "AU$" => Token::unit(AUD), "R$" => Token::unit(BRL), - "CA$" | "C$" => Token::unit(CAD), + "CA$" => Token::unit(CAD), "€" | "euro" | "euros" => Token::unit(EUR), "£" => Token::unit(GBP), "HK$" => Token::unit(HKD), "₹" | "Rs" => Token::unit(INR), "₪" => Token::unit(ILS), - "¥" => Token::unit(JPY), - "₩" => Token::unit(KRW), + "CN¥" => Token::unit(CNY), + "JP¥" => Token::unit(JPY), + "¥" => match get_region().as_str() { + "JP" => Token::unit(JPY), + "CN" => Token::unit(CNY), + region => return Err(format!("\"¥\" is ambiguous in your region \"{region}\"")), + }, + "₩" => match get_region().as_str() { + "KP" => Token::unit(KPW), + _ => Token::unit(KRW), + }, "MX$" => Token::unit(MXN), "NZ$" => Token::unit(NZD), "₱" => Token::unit(PHP), @@ -665,8 +674,48 @@ fn lex_word(word: &str, lexer: &mut Lexer) -> Result<(), String> { "฿" => Token::unit(THB), "tl" | "₺" => Token::unit(TRY), "₴" => Token::unit(UAH), - "$" | "US$" => Token::unit(USD), - "₫" => Token::unit(VND), + "US$" => Token::unit(USD), + "$" => match get_region().as_str() { + "CA" => Token::unit(CAD), + "AU" | "TV" | "KI" => Token::unit(AUD), + "NZ" => Token::unit(NZD), + "SG" => Token::unit(SGD), + "BS" => Token::unit(BSD), + "BB" => Token::unit(BBD), + "BZ" => Token::unit(BZD), + "BM" => Token::unit(BMD), + "BN" => Token::unit(BND), + "KY" => Token::unit(KYD), + "HK" => Token::unit(HKD), + "TW" => Token::unit(TWD), + "JM" => Token::unit(JMD), + "GY" => Token::unit(GYD), + "SR" => Token::unit(SRD), + "TT" => Token::unit(TTD), + "SB" => Token::unit(SBD), + "FJ" => Token::unit(FJD), + "NA" => Token::unit(NAD), + "LR" => Token::unit(LRD), + "AG" | "DM" | "GD" | "KN" | "LC" | "VC" | "MS" | "AI" => Token::unit(XCD), + "MX" => Token::unit(MXN), + "AR" => Token::unit(ARS), + "CL" => Token::unit(CLP), + "CO" => Token::unit(COP), + "CU" => Token::unit(CUP), + "DO" => Token::unit(DOP), + "UY" => Token::unit(UYU), + "MO" => Token::unit(MOP), + _ => Token::unit(USD), + }, + "₫" | "đ" | "Đ" => Token::unit(VND), + "kč" | "kc" => Token::unit(CZK), + "kr" => match get_region().as_str() { + "NO" => Token::unit(NOK), + "SE" => Token::unit(SEK), + "DK" => Token::unit(DKK), + "IS" => Token::unit(ISK), + region => return Err(format!("\"kr\" is ambiguous in your region \"{region}\"")), + }, string if let Ok(unit) = currency_code_to_unit(string) => Token::unit(unit), string => {