Upgrade ICU crates to 2.x (#5761)

This commit is contained in:
Quentin Gliech authored and GitHub committed 2026-07-02 12:09:49 +02:00
commit 7d249dccb9
14 files changed
+312 -304

No files matched your search

Generated
+210 -161
View File
@@ -793,9 +793,9 @@ dependencies = [
[[package]]
name = "calendrical_calculations"
version = "0.1.2"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ca2b6e2f7d75f43e001ded6f25e79b80bded5abbe764cbdf78c25a3051f4b"
checksum = "5abbd6eeda6885048d357edc66748eea6e0268e3dd11f326fff5bd248d779c26"
dependencies = [
"core_maths",
"displaydoc",
@@ -1791,9 +1791,9 @@ checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db"
[[package]]
name = "fixed_decimal"
version = "0.5.6"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0febbeb1118a9ecdee6e4520ead6b54882e843dd0592ad233247dbee84c53db8"
checksum = "79c3c892f121fff406e5dd6b28c1b30096b95111c30701a899d4f2b18da6d1bd"
dependencies = [
"displaydoc",
"smallvec",
@@ -2375,34 +2375,59 @@ dependencies = [
[[package]]
name = "icu_calendar"
version = "1.5.2"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7265b2137f9a36f7634a308d91f984574bbdba8cfd95ceffe1c345552275a8ff"
checksum = "a2b2acc6263f494f1df50685b53ff8e57869e47d5c6fe39c23d518ae9a4f3e45"
dependencies = [
"calendrical_calculations",
"displaydoc",
"icu_calendar_data",
"icu_locid",
"icu_locid_transform",
"icu_locale",
"icu_locale_core",
"icu_provider",
"ixdtf",
"tinystr",
"writeable",
"zerovec",
]
[[package]]
name = "icu_calendar_data"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "820499e77e852162190608b4f444e7b4552619150eafc39a9e39333d9efae9e1"
checksum = "118577bcf3a0fa7c6ac0a7d6e951814da84ee56b9b1f68fb4d8d10b08cefaf4d"
[[package]]
name = "icu_casemap"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "070f98b5b82798fcb93654bf96ed9f40064fc44c86f51a09ea711092cd5cc5be"
dependencies = [
"icu_casemap_data",
"icu_collections",
"icu_locale_core",
"icu_properties",
"icu_provider",
"potential_utf",
"writeable",
"zerovec",
]
[[package]]
name = "icu_casemap_data"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "846b0857ca091204be3c874bc93daaf89d4777e8d2d20b0d3ffe8f671d98014b"
[[package]]
name = "icu_collections"
version = "1.5.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c"
dependencies = [
"displaydoc",
"potential_utf",
"serde",
"utf8_iter",
"yoke",
"zerofrom",
"zerovec",
@@ -2410,22 +2435,22 @@ dependencies = [
[[package]]
name = "icu_datetime"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d115efb85e08df3fd77e77f52e7e087545a783fffba8be80bfa2102f306b1780"
checksum = "989d56ea5bbc43ae2b4e0388874b002884eaf4ed3a76c84a6c8c5ad575e04d72"
dependencies = [
"displaydoc",
"either",
"fixed_decimal",
"icu_calendar",
"icu_datetime_data",
"icu_decimal",
"icu_locid",
"icu_locid_transform",
"icu_locale",
"icu_locale_core",
"icu_pattern",
"icu_plurals",
"icu_provider",
"icu_timezone",
"smallvec",
"icu_time",
"potential_utf",
"tinystr",
"writeable",
"zerovec",
@@ -2433,43 +2458,50 @@ dependencies = [
[[package]]
name = "icu_datetime_data"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef5f04076123cab1b7a926a7083db27fe0d7a0e575adb984854aae3f3a6507d"
checksum = "40d3cc1b690d9703202bc319692ac8a1f3a6390686f0930ff40542450fa34f0b"
[[package]]
name = "icu_decimal"
version = "1.5.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb8fd98f86ec0448d85e1edf8884e4e318bb2e121bd733ec929a05c0a5e8b0eb"
checksum = "288247df2e32aa776ac54fdd64de552149ac43cb840f2761811f0e8d09719dd4"
dependencies = [
"displaydoc",
"fixed_decimal",
"icu_decimal_data",
"icu_locid_transform",
"icu_locale",
"icu_locale_core",
"icu_pattern",
"icu_plurals",
"icu_provider",
"writeable",
"zerovec",
]
[[package]]
name = "icu_decimal_data"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c95dd97f5ccf6d837a9c115496ec7d36646fa86ca18e7f1412115b4c820ae2"
checksum = "6f14a5ca9e8af29eef62064f269078424283d90dbaffeac5225addf62aaabc22"
[[package]]
name = "icu_experimental"
version = "0.1.0"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "844ad7b682a165c758065d694bc4d74ac67f176da1c499a04d85d492c0f193b7"
checksum = "0a881116e620fd635f564fd9cb9bc36c256b9da2221df8b3f55643d8ef32140f"
dependencies = [
"displaydoc",
"either",
"fixed_decimal",
"icu_casemap",
"icu_collections",
"icu_decimal",
"icu_experimental_data",
"icu_locid",
"icu_locid_transform",
"icu_list",
"icu_locale",
"icu_locale_core",
"icu_normalizer",
"icu_pattern",
"icu_plurals",
@@ -2479,60 +2511,81 @@ dependencies = [
"num-bigint",
"num-rational",
"num-traits",
"potential_utf",
"smallvec",
"tinystr",
"writeable",
"zerofrom",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_experimental_data"
version = "0.1.1"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121df92eafb8f5286d4e8ff401c1e7db8384377f806db3f8db77b91e5b7bd4dd"
checksum = "f72090d4f08a2bc94565cb02de6d5b87939424e462d9927d73a34f6f8e5d1232"
[[package]]
name = "icu_locid"
version = "1.5.0"
name = "icu_list"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
checksum = "aeeaf517689324395bed4767f7c65504f5455942ed4c14ee54c2087ca00b816e"
dependencies = [
"icu_list_data",
"icu_locale",
"icu_provider",
"regex-automata",
"writeable",
"zerovec",
]
[[package]]
name = "icu_list_data"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed62dbf114db9a4163481ed071509c4cd52cbcef9cb85979eba08a95549d73f3"
[[package]]
name = "icu_locale"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5a396343c7208121dc86e35623d3dfe19814a7613cfd14964994cdc9c9a2e26"
dependencies = [
"icu_collections",
"icu_locale_core",
"icu_locale_data",
"icu_provider",
"potential_utf",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_locale_core"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29"
dependencies = [
"displaydoc",
"litemap",
"serde",
"tinystr",
"writeable",
"zerovec",
]
[[package]]
name = "icu_locid_transform"
version = "1.5.0"
name = "icu_locale_data"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
dependencies = [
"displaydoc",
"icu_locid",
"icu_locid_transform_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_locid_transform_data"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d"
checksum = "d5fdcc9ac77c6d74ff5cf6e65ef3181d6af32003b16fce3a77fb451d2f695993"
[[package]]
name = "icu_normalizer"
version = "1.5.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4"
dependencies = [
"displaydoc",
"icu_collections",
"icu_normalizer_data",
"icu_properties",
@@ -2546,32 +2599,32 @@ dependencies = [
[[package]]
name = "icu_normalizer_data"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7"
checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38"
[[package]]
name = "icu_pattern"
version = "0.2.0"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7f36aafd098d6717de34e668a8120822275c1fba22b936e757b7de8a2fd7e4"
checksum = "1c4c568054ffe735398a9f4c55aec37ad7c768844553cc0978f09cc9b933a1fb"
dependencies = [
"displaydoc",
"either",
"serde",
"writeable",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_plurals"
version = "1.5.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a70e7c025dbd5c501b0a5c188cd11666a424f0dadcd4f0a95b7dafde3b114"
checksum = "2a50023f1d49ad5c4333380328a0d4a19e4b9d6d842ec06639affd5ba47c8103"
dependencies = [
"displaydoc",
"fixed_decimal",
"icu_locid_transform",
"icu_locale",
"icu_plurals_data",
"icu_provider",
"zerovec",
@@ -2579,92 +2632,71 @@ dependencies = [
[[package]]
name = "icu_plurals_data"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a483403238cb7d6a876a77a5f8191780336d80fe7b8b00bfdeb20be6abbfd112"
checksum = "8485497155dc865f901decb93ecc20d3e467df67bfeceb91e3ba34e2b11e8e1d"
[[package]]
name = "icu_properties"
version = "1.5.1"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de"
dependencies = [
"displaydoc",
"icu_collections",
"icu_locid_transform",
"icu_locale_core",
"icu_properties_data",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_properties_data"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2"
[[package]]
name = "icu_provider"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
dependencies = [
"displaydoc",
"icu_locid",
"icu_provider_macros",
"stable_deref_trait",
"tinystr",
"writeable",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "icu_provider_adapters"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6324dfd08348a8e0374a447ebd334044d766b1839bb8d5ccf2482a99a77c0bc"
dependencies = [
"icu_locid",
"icu_locid_transform",
"icu_provider",
"tinystr",
"zerovec",
]
[[package]]
name = "icu_provider_macros"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "icu_timezone"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa91ba6a585939a020c787235daa8aee856d9bceebd6355e283c0c310bc6de96"
dependencies = [
"displaydoc",
"icu_calendar",
"icu_provider",
"icu_timezone_data",
"tinystr",
"serde",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_timezone_data"
version = "1.5.1"
name = "icu_properties_data"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1adcf7b613a268af025bc2a2532b4b9ee294e6051c5c0832d8bff20ac0232e68"
checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14"
[[package]]
name = "icu_provider"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421"
dependencies = [
"displaydoc",
"icu_locale_core",
"serde",
"stable_deref_trait",
"writeable",
"yoke",
"zerofrom",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_time"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec3af0c141da0a61d4f6970cd1d5f4b388b17ea22f8124f8f6049d3d5147586a"
dependencies = [
"calendrical_calculations",
"displaydoc",
"icu_calendar",
"icu_locale_core",
"icu_provider",
"icu_time_data",
"ixdtf",
"serde",
"zerotrie",
"zerovec",
]
[[package]]
name = "icu_time_data"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f2f8aeca682d874a5247084aa4fb7d1cef9ba45d889c21209a8818dcaaa0ec9"
[[package]]
name = "id-arena"
@@ -2691,9 +2723,9 @@ dependencies = [
[[package]]
name = "idna_adapter"
version = "1.2.0"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
dependencies = [
"icu_normalizer",
"icu_properties",
@@ -2812,6 +2844,12 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "ixdtf"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ceaf4c6c48465bead8cb6a0b7c4ee0c86ecbb31239032b9c66ab9a08d2f3ee1"
[[package]]
name = "jiff"
version = "0.2.28"
@@ -3074,9 +3112,9 @@ dependencies = [
[[package]]
name = "litemap"
version = "0.7.5"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0"
[[package]]
name = "litrs"
@@ -3123,7 +3161,7 @@ dependencies = [
"chrono",
"headers",
"http",
"icu_locid",
"icu_locale_core",
"mas-context",
"mas-data-model",
"mas-http",
@@ -3412,14 +3450,12 @@ name = "mas-i18n"
version = "1.20.0-rc.0"
dependencies = [
"camino",
"icu_calendar",
"icu_datetime",
"icu_experimental",
"icu_locid",
"icu_locid_transform",
"icu_locale",
"icu_locale_core",
"icu_plurals",
"icu_provider",
"icu_provider_adapters",
"pad",
"pest",
"pest_derive",
@@ -4630,6 +4666,17 @@ dependencies = [
"serde",
]
[[package]]
name = "potential_utf"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564"
dependencies = [
"serde_core",
"writeable",
"zerovec",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
@@ -6349,11 +6396,12 @@ dependencies = [
[[package]]
name = "tinystr"
version = "0.7.6"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d"
dependencies = [
"displaydoc",
"serde_core",
"zerovec",
]
@@ -7777,9 +7825,9 @@ checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
[[package]]
name = "writeable"
version = "0.5.5"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4"
dependencies = [
"either",
]
@@ -7792,11 +7840,10 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yoke"
version = "0.7.5"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5"
dependencies = [
"serde",
"stable_deref_trait",
"yoke-derive",
"zerofrom",
@@ -7804,9 +7851,9 @@ dependencies = [
[[package]]
name = "yoke-derive"
version = "0.7.5"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
dependencies = [
"proc-macro2",
"quote",
@@ -7863,21 +7910,23 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
[[package]]
name = "zerotrie"
version = "0.1.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb594dd55d87335c5f60177cee24f19457a5ec10a065e0a3014722ad252d0a1f"
checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf"
dependencies = [
"displaydoc",
"yoke",
"zerofrom",
"zerovec",
]
[[package]]
name = "zerovec"
version = "0.10.4"
version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239"
dependencies = [
"serde",
"yoke",
"zerofrom",
"zerovec-derive",
@@ -7885,9 +7934,9 @@ dependencies = [
[[package]]
name = "zerovec-derive"
version = "0.10.3"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
dependencies = [
"proc-macro2",
"quote",
+17 -20
View File
@@ -301,31 +301,28 @@ default-features = false
# ICU libraries for internationalization
[workspace.dependencies.icu_calendar]
version = "1.5.2"
features = ["compiled_data", "std"]
version = "2.2.1"
features = ["compiled_data"]
[workspace.dependencies.icu_datetime]
version = "1.5.1"
features = ["compiled_data", "std"]
version = "2.2.0"
features = ["compiled_data"]
[workspace.dependencies.icu_experimental]
version = "0.1.0"
features = ["compiled_data", "std"]
[workspace.dependencies.icu_locid]
version = "1.5.0"
features = ["std"]
[workspace.dependencies.icu_locid_transform]
version = "1.5.0"
features = ["compiled_data", "std"]
version = "0.5.0"
features = ["compiled_data"]
[workspace.dependencies.icu_locale]
version = "2.2.0"
features = ["compiled_data"]
[workspace.dependencies.icu_locale_core]
version = "2.2.0"
[workspace.dependencies.icu_normalizer]
version = "1.5.0"
version = "2.2.0"
features = ["compiled_data"]
[workspace.dependencies.icu_plurals]
version = "1.5.0"
features = ["compiled_data", "std"]
version = "2.2.0"
features = ["compiled_data"]
[workspace.dependencies.icu_provider]
version = "1.5.0"
version = "2.2.0"
features = ["std", "sync"]
[workspace.dependencies.icu_provider_adapters]
version = "1.5.0"
features = ["std"]
# HashMap which preserves insertion order
[workspace.dependencies.indexmap]
@@ -740,7 +737,7 @@ version = "0.13.0"
# String writing interface
[workspace.dependencies.writeable]
version = "0.5.5"
version = "0.6.3"
# Zero memory after use
[workspace.dependencies.zeroize]
+1 -1
View File
@@ -24,7 +24,7 @@ base64ct.workspace = true
chrono.workspace = true
headers.workspace = true
http.workspace = true
icu_locid.workspace = true
icu_locale_core.workspace = true
mime.workspace = true
rand.workspace = true
reqwest.workspace = true
+4 -3
View File
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
@@ -8,7 +9,7 @@ use std::cmp::Reverse;
use headers::{Error, Header};
use http::{HeaderName, HeaderValue, header::ACCEPT_LANGUAGE};
use icu_locid::Locale;
use icu_locale_core::Locale;
#[derive(PartialEq, Eq, Debug)]
struct AcceptLanguagePart {
@@ -90,7 +91,7 @@ impl Header for AcceptLanguage {
b"*" => None,
locale => {
let locale =
Locale::try_from_bytes(locale).map_err(|_e| Error::invalid())?;
Locale::try_from_utf8(locale).map_err(|_e| Error::invalid())?;
Some(locale)
}
};
@@ -156,7 +157,7 @@ impl Header for AcceptLanguage {
mod tests {
use headers::HeaderMapExt;
use http::{HeaderMap, HeaderValue, header::ACCEPT_LANGUAGE};
use icu_locid::locale;
use icu_locale_core::locale;
use super::*;
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2021-2024 The Matrix.org Foundation C.I.C.
//
@@ -154,7 +155,6 @@ pub(crate) async fn get(
let res: Result<Response, RouteError> = ({
let templates = templates.clone();
let callback_destination = callback_destination.clone();
let locale = locale.clone();
async move {
let maybe_session = session_info.load_active_session(&mut repo).await?;
let prompt = params.auth.prompt.as_deref().unwrap_or_default();
+2 -1
View File
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
@@ -142,7 +143,7 @@ async fn handle_code(
let ctx = DeviceLinkContext::new()
.with_form_state(form_state)
.with_csrf(csrf_token.form_value())
.with_language(locale.clone());
.with_language(*locale);
let content = templates.render_device_link(&ctx)?;
+1
View File
@@ -262,6 +262,7 @@ impl IntoResponse for RouteError {
}
impl_from_error_for_route!(mas_i18n::DataError);
impl_from_error_for_route!(mas_i18n::ParseError);
impl_from_error_for_route!(mas_templates::TemplateError);
impl_from_error_for_route!(mas_storage::RepositoryError);
impl_from_error_for_route!(mas_policy::EvaluationError);
+3 -2
View File
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2022-2024 The Matrix.org Foundation C.I.C.
//
@@ -303,8 +304,8 @@ impl Hasher {
fn normalize_password(&self, password: Zeroizing<String>) -> Zeroizing<String> {
if self.unicode_normalization {
// This is the normalization method used by Synapse
let normalizer = icu_normalizer::ComposingNormalizer::new_nfkc();
Zeroizing::new(normalizer.normalize(&password))
let normalizer = icu_normalizer::ComposingNormalizerBorrowed::new_nfkc();
Zeroizing::new(normalizer.normalize(&password).into_owned())
} else {
password
}
+3 -3
View File
@@ -75,7 +75,7 @@ pub async fn load_session_or_fallback(
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock, rng);
let ctx = AccountInactiveContext::new(session.user)
.with_csrf(csrf_token.form_value())
.with_language(locale.clone());
.with_language(*locale);
let fallback = templates.render_account_deactivated(&ctx)?;
let response = (cookie_jar, Html(fallback)).into_response();
return Ok(SessionOrFallback::Fallback { response });
@@ -86,7 +86,7 @@ pub async fn load_session_or_fallback(
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock, rng);
let ctx = AccountInactiveContext::new(session.user)
.with_csrf(csrf_token.form_value())
.with_language(locale.clone());
.with_language(*locale);
let fallback = templates.render_account_locked(&ctx)?;
let response = (cookie_jar, Html(fallback)).into_response();
return Ok(SessionOrFallback::Fallback { response });
@@ -100,7 +100,7 @@ pub async fn load_session_or_fallback(
let (csrf_token, cookie_jar) = cookie_jar.csrf_token(clock, rng);
let ctx = AccountInactiveContext::new(session.user)
.with_csrf(csrf_token.form_value())
.with_language(locale.clone());
.with_language(*locale);
let fallback = templates.render_account_logged_out(&ctx)?;
let response = (cookie_jar, Html(fallback)).into_response();
return Ok(SessionOrFallback::Fallback { response });
+2 -4
View File
@@ -18,13 +18,11 @@ workspace = true
[dependencies]
camino.workspace = true
icu_calendar.workspace = true
icu_datetime.workspace = true
icu_experimental.workspace = true
icu_locid_transform.workspace = true
icu_locid.workspace = true
icu_locale.workspace = true
icu_locale_core.workspace = true
icu_plurals.workspace = true
icu_provider_adapters.workspace = true
icu_provider.workspace = true
pad.workspace = true
pest_derive.workspace = true
+2 -2
View File
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
@@ -8,9 +9,8 @@ pub mod sprintf;
pub mod translations;
mod translator;
pub use icu_calendar;
pub use icu_datetime;
pub use icu_locid::locale;
pub use icu_locale_core::{ParseError, locale};
pub use icu_provider::{DataError, DataLocale};
pub use self::{
+47 -73
View File
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2023, 2024 The Matrix.org Foundation C.I.C.
//
@@ -10,38 +11,15 @@ use camino::{Utf8Path, Utf8PathBuf};
use icu_experimental::relativetime::{
RelativeTimeFormatter, RelativeTimeFormatterOptions, options::Numeric,
};
use icu_locid::{Locale, ParserError};
use icu_locid_transform::fallback::{
LocaleFallbackPriority, LocaleFallbackSupplement, LocaleFallbacker, LocaleFallbackerWithConfig,
};
use icu_plurals::{PluralRules, PluralsError};
use icu_provider::{
DataError, DataErrorKind, DataKey, DataLocale, DataRequest, DataRequestMetadata, data_key,
fallback::LocaleFallbackConfig,
};
use icu_provider_adapters::fallback::LocaleFallbackProvider;
use icu_locale::fallback::{LocaleFallbackConfig, LocaleFallbacker};
use icu_locale_core::{Locale, ParseError};
use icu_plurals::PluralRules;
use icu_provider::{DataError, DataErrorKind, DataLocale};
use thiserror::Error;
use writeable::Writeable;
use crate::{sprintf::Message, translations::TranslationTree};
/// Fake data key for errors
const DATA_KEY: DataKey = data_key!("mas/translations@1");
const FALLBACKER: LocaleFallbackerWithConfig<'static> = LocaleFallbacker::new().for_config({
let mut config = LocaleFallbackConfig::const_default();
config.priority = LocaleFallbackPriority::Collation;
config.fallback_supplement = Some(LocaleFallbackSupplement::Collation);
config
});
/// Construct a [`DataRequest`] for the given locale
pub fn data_request_for_locale(locale: &DataLocale) -> DataRequest<'_> {
let mut metadata = DataRequestMetadata::default();
metadata.silent = true;
DataRequest { locale, metadata }
}
/// Error type for loading translations
#[derive(Debug, Error)]
pub enum LoadError {
@@ -70,7 +48,7 @@ pub enum LoadError {
InvalidLocale {
path: Utf8PathBuf,
#[source]
source: ParserError,
source: ParseError,
},
#[error("Invalid file name {path:?}")]
@@ -81,7 +59,7 @@ pub enum LoadError {
#[derive(Debug)]
pub struct Translator {
translations: HashMap<DataLocale, TranslationTree>,
plural_provider: LocaleFallbackProvider<icu_plurals::provider::Baked>,
fallbacker: LocaleFallbacker,
default_locale: DataLocale,
}
@@ -90,16 +68,12 @@ impl Translator {
#[must_use]
pub fn new(translations: HashMap<DataLocale, TranslationTree>) -> Self {
let fallbacker = LocaleFallbacker::new().static_to_owned();
let plural_provider = LocaleFallbackProvider::new_with_fallbacker(
icu_plurals::provider::Baked,
fallbacker.clone(),
);
Self {
translations,
plural_provider,
fallbacker,
// TODO: make this configurable
default_locale: icu_locid::locale!("en").into(),
default_locale: icu_locale_core::locale!("en").into(),
}
}
@@ -176,7 +150,10 @@ impl Translator {
return Some((message, locale));
}
let mut iter = FALLBACKER.fallback_for(locale);
let mut iter = self
.fallbacker
.for_config(LocaleFallbackConfig::default())
.fallback_for(locale);
loop {
let locale = iter.get();
@@ -186,9 +163,9 @@ impl Translator {
}
// Try the defaut locale if we hit the `und` locale
if locale.is_und() {
if locale.is_unknown() {
let message = self.message(&self.default_locale, key).ok()?;
return Some((message, self.default_locale.clone()));
return Some((message, self.default_locale));
}
iter.step();
@@ -207,16 +184,14 @@ impl Translator {
/// Returns an error if the requested locale is not found, or if the
/// requested key is not found.
pub fn message(&self, locale: &DataLocale, key: &str) -> Result<&Message, DataError> {
let request = data_request_for_locale(locale);
let tree = self
.translations
.get(locale)
.ok_or_else(|| DataErrorKind::MissingLocale.with_req(DATA_KEY, request))?;
.ok_or_else(|| DataErrorKind::IdentifierNotFound.into_error())?;
let message = tree
.message(key)
.ok_or_else(|| DataErrorKind::MissingDataKey.with_req(DATA_KEY, request))?;
.ok_or_else(|| DataErrorKind::MarkerNotFound.into_error())?;
Ok(message)
}
@@ -238,7 +213,10 @@ impl Translator {
key: &str,
count: usize,
) -> Option<(&Message, DataLocale)> {
let mut iter = FALLBACKER.fallback_for(locale);
let mut iter = self
.fallbacker
.for_config(LocaleFallbackConfig::default())
.fallback_for(locale);
loop {
let locale = iter.get();
@@ -248,7 +226,7 @@ impl Translator {
}
// Stop if we hit the `und` locale
if locale.is_und() {
if locale.is_unknown() {
return None;
}
@@ -273,20 +251,18 @@ impl Translator {
locale: &DataLocale,
key: &str,
count: usize,
) -> Result<&Message, PluralsError> {
let plurals = PluralRules::try_new_cardinal_unstable(&self.plural_provider, locale)?;
) -> Result<&Message, DataError> {
let plurals = PluralRules::try_new_cardinal(locale.into_locale().into())?;
let category = plurals.category_for(count);
let request = data_request_for_locale(locale);
let tree = self
.translations
.get(locale)
.ok_or_else(|| DataErrorKind::MissingLocale.with_req(DATA_KEY, request))?;
.ok_or_else(|| DataErrorKind::IdentifierNotFound.into_error())?;
let message = tree
.pluralize(key, category)
.ok_or_else(|| DataErrorKind::MissingDataKey.with_req(DATA_KEY, request))?;
.ok_or_else(|| DataErrorKind::MarkerNotFound.into_error())?;
Ok(message)
}
@@ -302,18 +278,13 @@ impl Translator {
/// # Errors
///
/// Returns an error if the requested locale is not found.
pub fn relative_date(
&self,
locale: &DataLocale,
days: i64,
) -> Result<String, icu_experimental::relativetime::RelativeTimeError> {
pub fn relative_date(&self, locale: &DataLocale, days: i64) -> Result<String, DataError> {
let mut options = RelativeTimeFormatterOptions::default();
options.numeric = Numeric::Auto;
// TODO: this is not using the fallbacker
let formatter = RelativeTimeFormatter::try_new_long_day(
locale,
RelativeTimeFormatterOptions {
numeric: Numeric::Auto,
},
)?;
let formatter =
RelativeTimeFormatter::try_new_long_day(locale.into_locale().into(), options)?;
let date = formatter.format(days.into());
Ok(date.write_to_string().into_owned())
@@ -329,24 +300,24 @@ impl Translator {
/// # Errors
///
/// Returns an error if the requested locale is not found.
pub fn short_time<T: icu_datetime::input::IsoTimeInput>(
pub fn short_time(
&self,
locale: &DataLocale,
time: &T,
) -> Result<String, icu_datetime::DateTimeError> {
time: &icu_datetime::input::Time,
) -> Result<String, icu_datetime::DateTimeFormatterLoadError> {
// TODO: this is not using the fallbacker
let formatter = icu_datetime::TimeFormatter::try_new_with_length(
locale,
icu_datetime::options::length::Time::Short,
let formatter = icu_datetime::NoCalendarFormatter::try_new(
locale.into_locale().into(),
icu_datetime::fieldsets::T::short(),
)?;
Ok(formatter.format_to_string(time))
Ok(formatter.format(time).to_string())
}
/// Get a list of available locales.
#[must_use]
pub fn available_locales(&self) -> Vec<DataLocale> {
self.translations.keys().cloned().collect()
self.translations.keys().copied().collect()
}
/// Check if a locale is available.
@@ -363,10 +334,13 @@ impl Translator {
return locale;
}
let mut fallbacker = FALLBACKER.fallback_for(locale);
let mut fallbacker = self
.fallbacker
.for_config(LocaleFallbackConfig::default())
.fallback_for(locale);
loop {
if fallbacker.get().is_und() {
if fallbacker.get().is_unknown() {
break;
}
@@ -377,14 +351,14 @@ impl Translator {
}
}
self.default_locale.clone()
self.default_locale
}
}
#[cfg(test)]
mod tests {
use camino::Utf8PathBuf;
use icu_locid::locale;
use icu_locale_core::locale;
use crate::{sprintf::arg_list, translator::Translator};
+3 -2
View File
@@ -1,3 +1,4 @@
// Copyright 2025, 2026 Element Creations Ltd.
// Copyright 2024, 2025 New Vector Ltd.
// Copyright 2024 The Matrix.org Foundation C.I.C.
//
@@ -93,8 +94,8 @@ impl RunnableJob for SendAccountRecoveryEmailsJob {
let mailbox = Mailbox::new(Some(user.username.clone()), address);
info!("Sending recovery email to {}", mailbox);
let context = EmailRecoveryContext::new(user, session.clone(), url)
.with_language(lang.clone());
let context =
EmailRecoveryContext::new(user, session.clone(), url).with_language(lang);
// XXX: we only log if the email fails to send, to avoid stopping the loop
if let Err(e) = mailer.send_recovery_email(mailbox, &context).await {
+16 -31
View File
@@ -277,14 +277,14 @@ impl Object for TranslateFunc {
let (message, _locale) = if let Some(count) = kwargs.get("count")? {
self.translator
.plural_with_fallback(self.lang.clone(), key, count)
.plural_with_fallback(self.lang, key, count)
.ok_or(Error::new(
ErrorKind::InvalidOperation,
"Missing translation",
))?
} else {
self.translator
.message_with_fallback(self.lang.clone(), key)
.message_with_fallback(self.lang, key)
.ok_or(Error::new(
ErrorKind::InvalidOperation,
"Missing translation",
@@ -363,6 +363,8 @@ impl Object for TranslateFunc {
}
"short_time" => {
use chrono::Timelike as _;
let (date,): (String,) = from_args(args)?;
let date: chrono::DateTime<chrono::Utc> = date.parse().map_err(|e| {
Error::new(
@@ -375,9 +377,20 @@ impl Object for TranslateFunc {
// TODO: we should use the user's timezone here
let time = date.time();
// The hour, minute and second always fit in a `u8`.
let time = mas_i18n::icu_datetime::input::Time::try_new(
time.hour().try_into().unwrap_or(0),
time.minute().try_into().unwrap_or(0),
time.second().try_into().unwrap_or(0),
time.nanosecond(),
)
.map_err(|e| {
Error::new(ErrorKind::InvalidOperation, "Invalid time").with_source(e)
})?;
Ok(Value::from(
self.translator
.short_time(&self.lang, &TimeAdapter(time))
.short_time(&self.lang, &time)
.map_err(|_e| {
Error::new(ErrorKind::InvalidOperation, "Failed to format time")
})?,
@@ -392,34 +405,6 @@ impl Object for TranslateFunc {
}
}
/// An adapter to make a [`Timelike`] implement [`IsoTimeInput`]
///
/// [`Timelike`]: chrono::Timelike
/// [`IsoTimeInput`]: mas_i18n::icu_datetime::input::IsoTimeInput
struct TimeAdapter<T>(T);
impl<T: chrono::Timelike> mas_i18n::icu_datetime::input::IsoTimeInput for TimeAdapter<T> {
fn hour(&self) -> Option<mas_i18n::icu_calendar::types::IsoHour> {
let hour: usize = chrono::Timelike::hour(&self.0).try_into().ok()?;
hour.try_into().ok()
}
fn minute(&self) -> Option<mas_i18n::icu_calendar::types::IsoMinute> {
let minute: usize = chrono::Timelike::minute(&self.0).try_into().ok()?;
minute.try_into().ok()
}
fn second(&self) -> Option<mas_i18n::icu_calendar::types::IsoSecond> {
let second: usize = chrono::Timelike::second(&self.0).try_into().ok()?;
second.try_into().ok()
}
fn nanosecond(&self) -> Option<mas_i18n::icu_calendar::types::NanoSecond> {
let nanosecond: usize = chrono::Timelike::nanosecond(&self.0).try_into().ok()?;
nanosecond.try_into().ok()
}
}
#[derive(Default, Debug)]
struct IncludedAssetsTrackerInner {
preloaded: HashSet<Utf8PathBuf>,