diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
commit | 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 (patch) | |
tree | d325add32978dbdc1db975a438b3a77d571b1ab8 /vendor/icu_locid | |
parent | Releasing progress-linux version 1.68.2+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.tar.xz rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/icu_locid')
32 files changed, 771 insertions, 542 deletions
diff --git a/vendor/icu_locid/.cargo-checksum.json b/vendor/icu_locid/.cargo-checksum.json index 1f1097bd7..1ea6414e8 100644 --- a/vendor/icu_locid/.cargo-checksum.json +++ b/vendor/icu_locid/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.lock":"6bf9c8304a3fe9f99d7189f9a082be2c7859ea164976975069f8fd2f7f80bbbd","Cargo.toml":"44c6bcdc448226df67e425cb00bf02596c96d0a0bfcb3951d3a5d0998afaa60d","LICENSE":"4ad7541d66a407234e2c84902124cef325c29f3e966353efdb800bedb8b8da21","README.md":"d0e5ced27519cf715a66dc4fece18c8cacece8dbb81eb1e03ab82dd57f0bc7f5","benches/fixtures/langid.json":"373c11527653c63c685c9e229a8de5ae2b557c25b686a9d891c59e1f603232d8","benches/fixtures/locale.json":"669b19db933094290a45bf856559920f4e92401072e364ac82c482119dc9233a","benches/fixtures/mod.rs":"9a9671eddcf38a6faa10cb814949f8abc15d89f5e70f3ad6f684f1bc3ffe72ea","benches/fixtures/subtags.json":"28be3a639e452d713e807d5779b6819e06277e2dbbf67801ef34964fb9b074b6","benches/helpers/macros.rs":"bba0945a826bc083156bc302507c48c0c99c4d965e2a84352644d768591b0339","benches/helpers/mod.rs":"c98167d866fdb7f66c8cab41e8d57b5aab9e9707dfc66c37ef136e088dac6fef","benches/iai_langid.rs":"675ab67edc2820894e1179e97e3aad6037957084efa07e494c17c40f3c0bbe35","benches/langid.rs":"4e3d307d48fd9071308a567a0ef927b229814978abd2ba29f57c65edd51f38e4","benches/locale.rs":"b8d5b1e3f8b5578c549a5149229656fb60de26b76a1bf66b6c1abce75042d674","benches/subtags.rs":"e7e80dabaf31bf031779456614f139cafcdadb805986e71b49133ac964928432","examples/filter_langids.rs":"28bea5b7dc715d6c00694437c3f12a72cf68dc984bb13acbb7b1ce5f97c5726a","examples/syntatically_canonicalize_locales.rs":"de97579c82f1670629d077a6216ecce06761da28715387f46250f81b8172ae6b","src/extensions/mod.rs":"76efffe1c99da3ef61a93f8174267e4b0b63abc3283ec8e0c5170ebc582263fe","src/extensions/other/mod.rs":"4216cd8a4dcef13105b48e507659920feaaa3fa3aebc2ba8d7702b40bbec2881","src/extensions/other/subtag.rs":"cb52ec1acec55e4c0e1d37cc5a552d11010051d827786202702257c8fcd96c49","src/extensions/private/mod.rs":"961bfb455114ad7166beb5acb36a1b182d2e81d99cccbfd3b3bf68853cae490d","src/extensions/private/other.rs":"586fd24398e78c5fda0afdb98de28a6467afd2d702683daf5dfab2a6c45af1e9","src/extensions/transform/fields.rs":"376ae5862329709d54b262a6d91be97bb02fc5e0198f30be8a2f4b0adc420c8b","src/extensions/transform/key.rs":"53e8c9ce13f00f678c2322855cc1d90afd91cd33a2af3758d098b7bbcc7090e5","src/extensions/transform/mod.rs":"c932d7e4484ac3bf3c9fe0c63b17847d8cb29f8874d71cd17070e63b8bca5998","src/extensions/transform/value.rs":"153c4edeb987e052dafe0790bcda560da4dcfa6897e5aaf3f62ae772b0605009","src/extensions/unicode/attribute.rs":"d558a193b72f54cdb03afe8e023a145ac74832c8416ca55401cd417ebba2431c","src/extensions/unicode/attributes.rs":"f2f13714750035ff805455b43ba665710978d13b90a53358314e798662c436b6","src/extensions/unicode/key.rs":"6c8694527079c5dd5f03f8e85f23ae6b5aa4b47899d1047036960e8400dca7de","src/extensions/unicode/keywords.rs":"58a2eca7c5e6ac6ad6812538a5b8118e35274c6b5de8029d55cbe1b4cd0a4abb","src/extensions/unicode/mod.rs":"e81db13fdb2db8d6cf7cfcd7c0d926b929fceca500894e688768b3494d02d0c3","src/extensions/unicode/value.rs":"02876ed95059d21d09ff2b986776d6bf0cb14c698237a86a9be24886ffd7a1cd","src/helpers.rs":"a6b8c22ef40a57339e4051fad54e724320851f827bc6f888187f30371024d04a","src/langid.rs":"b3258b1be6566dc117295a525dcb04237f0049c59dc91f460d939cd162ef8b39","src/lib.rs":"6f6248e20709be74b9e186b45810a4963ffa91c680be4ad78be9a6af5a10da5c","src/locale.rs":"a1ff7500d17581fe06524f6d70d59f0765c5d5ca89cb64b42953b286b20727b4","src/macros.rs":"f7154fc103ea1120a55bb5898540b20df80de6eec42e70ce15f339d997f2bf52","src/ordering.rs":"c70aa4e33d5cbab8d75d2833641141b71984a93648634cfc57fc25c3f79a5f58","src/parser/errors.rs":"ccea5e49c109db3766a71ac4aab1d759e2351c4cd31816b6abdca166699c7f3e","src/parser/langid.rs":"ef5c3dc233a5cea1953688e69152c601a3260196caa9327dd07edc7b6be7b0b8","src/parser/locale.rs":"b7d4cd4ed80b0acae9e77046a3b4943ee19e4aec395e36951750da32366b9a8e","src/parser/mod.rs":"c65268221fc67a692a2a647b08dd81b244a9186c04f5ab0837383dcaa983b740","src/serde.rs":"06e940e4f2d15f02d313b4e2b233aea3e74c93c6c43076f5ffe52d49c133608f","src/subtags/language.rs":"e9dc6de6c6aebb6d8bf6e55f1ae9fab41844a52e681b4309e625a5076c02f9f3","src/subtags/mod.rs":"0257f746ed368ea3fa675054c9e7e40d972ec31cd7cc525be655a16a83c9d17b","src/subtags/region.rs":"4f4120f4910d0a4496f29c193d00313e71be4c646867d97ebd0e9a7438693847","src/subtags/script.rs":"6b1a68783cb90409bdd39b0184dfb2cb1c302fdee7202e3b6f7c7c8941bc7dfe","src/subtags/variant.rs":"956f1ea3d98172b6ead333411f010cf4e84404584a3051cb775d148d79beb4f8","src/subtags/variants.rs":"7740d1b20f596b04f509db917e9c2fffba80a013ffc42f0046cdc2d32b088aeb","src/zerovec.rs":"9d01a235d18296fbf0c2e89d188459e9446df0e63aaedc7e150165604af885b9","tests/fixtures/canonicalize.json":"9f2b7cbef72c24944cd4dc50de368c6e3ef69949f29c9ce1aa8807de767a4d0a","tests/fixtures/invalid-extensions.json":"0af95f38e458c8f52760f76c6540993beb9ba9421a3967df0cd6abb9fe2ce21a","tests/fixtures/invalid.json":"1f1ae207f1ce886b3f57cfcdfb2525aa3e58d538f997b2bda4088062de7aa68d","tests/fixtures/langid.json":"960fd01722217ef1ea9077e2e0821d7089fe318a241bd7fb7918f50bf8f3f5c3","tests/fixtures/locale.json":"8606e0569fc6ea0e50a1fecb9295b911fbef7d8dbfde3c585476284a751baccf","tests/fixtures/mod.rs":"28dec3e5c9d766e148adbff6857dce884d9ff94f7ef8aee17fde0084cc78a7ee","tests/helpers/mod.rs":"d3bf59e7eed6230f340bef6c87a7b8de3a387ec391f60afc1b15a0d001cbfb67","tests/langid.rs":"2e21d576a6eaba000fbe88d52362384f460ba350cac1e7034a1661302000ac58","tests/locale.rs":"91af0a738ca5def89fdb4d7f8d3504ad7b757e1d7c8e4d24dc246de610b46a04"},"package":"34b3de5d99a0e275fe6193b9586dbf37364daebc0d39c89b5cf8376a53b789e8"}
\ No newline at end of file +{"files":{"Cargo.lock":"332fcd0f371d9ef54006d7525bfc6a8adae7433754a3fbc0328530f421d92d0d","Cargo.toml":"c60a23e3795ec4820118fc5dec6ffb9bdca684d95511de01ea5a04d6d8272bc8","LICENSE":"4ad7541d66a407234e2c84902124cef325c29f3e966353efdb800bedb8b8da21","README.md":"16472983782c836d9e97b4df4754baab7bb247d0a945d1a97cafb3210e951d8f","benches/fixtures/langid.json":"373c11527653c63c685c9e229a8de5ae2b557c25b686a9d891c59e1f603232d8","benches/fixtures/locale.json":"669b19db933094290a45bf856559920f4e92401072e364ac82c482119dc9233a","benches/fixtures/mod.rs":"9a9671eddcf38a6faa10cb814949f8abc15d89f5e70f3ad6f684f1bc3ffe72ea","benches/fixtures/subtags.json":"28be3a639e452d713e807d5779b6819e06277e2dbbf67801ef34964fb9b074b6","benches/helpers/macros.rs":"bba0945a826bc083156bc302507c48c0c99c4d965e2a84352644d768591b0339","benches/helpers/mod.rs":"c98167d866fdb7f66c8cab41e8d57b5aab9e9707dfc66c37ef136e088dac6fef","benches/iai_langid.rs":"7984d12b78a0e2ecfa1eac74ccf7310627285de821c13fab2fe000f0e961a136","benches/langid.rs":"4e3d307d48fd9071308a567a0ef927b229814978abd2ba29f57c65edd51f38e4","benches/locale.rs":"b8d5b1e3f8b5578c549a5149229656fb60de26b76a1bf66b6c1abce75042d674","benches/subtags.rs":"e7e80dabaf31bf031779456614f139cafcdadb805986e71b49133ac964928432","examples/filter_langids.rs":"f36f6732b08a954d41ea95dfb3f07963f7c120e80ed29f4de7c9ec562c0151d6","examples/syntatically_canonicalize_locales.rs":"de97579c82f1670629d077a6216ecce06761da28715387f46250f81b8172ae6b","src/extensions/mod.rs":"106af2b8186202aa8c654acc085619d99fdbdbc467c276ead8283b9938c75ba7","src/extensions/other/mod.rs":"ee377c2eeaa6b622a2c80807bffdd307800030fe2ec8a99a9729bdde45452635","src/extensions/other/subtag.rs":"431d27a0a5adca7d56c7ea3a6de2a0412e1e14ad2dd8a8e09a548849984b84b6","src/extensions/private/mod.rs":"5d53d32adb79386416b6eb4a9de218423f3bee4000e96e4899b78462f609531c","src/extensions/private/other.rs":"586fd24398e78c5fda0afdb98de28a6467afd2d702683daf5dfab2a6c45af1e9","src/extensions/transform/fields.rs":"9221478ce7565738bb27951a6be25b3ebc5c11d63afb2ca744fd4c587d155e9b","src/extensions/transform/key.rs":"53e8c9ce13f00f678c2322855cc1d90afd91cd33a2af3758d098b7bbcc7090e5","src/extensions/transform/mod.rs":"111ebf59ad6cd9a09a8eb84367a0053ff03fff8329f07310131784a457d07b61","src/extensions/transform/value.rs":"577b642b32f7a74e98ba5bee8e30700021c8b0e6da63538398aaf95d13edfd65","src/extensions/unicode/attribute.rs":"d558a193b72f54cdb03afe8e023a145ac74832c8416ca55401cd417ebba2431c","src/extensions/unicode/attributes.rs":"ddc0361968151e28cc1e6a3d91056a0f71f2c42f22dacecd339aaa67dfdcf899","src/extensions/unicode/key.rs":"6c8694527079c5dd5f03f8e85f23ae6b5aa4b47899d1047036960e8400dca7de","src/extensions/unicode/keywords.rs":"d98b0799c171557c9d042bcc06389ac9742ae0a4910d9ceb1612d1ac5045222c","src/extensions/unicode/mod.rs":"e066cbdabf567a40c777428d071e2e82389a043bd552bc1e83202401c86e0b2e","src/extensions/unicode/value.rs":"38b96501db9ebc3da583162d68279de30096b896209874ff052dcc10f874d98a","src/helpers.rs":"54272463a938a04fd2cf5a663128ea08f36744180f0eb49fa2ad7de105c0c19a","src/langid.rs":"77dce95dd5549c15cbfa9f34f3521f7ad1d1c1b16c3d972f28023f59283bd56f","src/lib.rs":"661efd6459894a1821861a8b7e0a7e73484c49f5d297810aed401f7a66c45985","src/locale.rs":"98c5389226e3dd2ae9378225c129d0eb264d5b1d712111f2587489d01feeb546","src/macros.rs":"f7154fc103ea1120a55bb5898540b20df80de6eec42e70ce15f339d997f2bf52","src/ordering.rs":"c70aa4e33d5cbab8d75d2833641141b71984a93648634cfc57fc25c3f79a5f58","src/parser/errors.rs":"44a25385a2dc7d537b3ce482fc02169eda1e5e727ee99b00f0fd85cb501ee939","src/parser/langid.rs":"749ac36945e7b5e24cbc82f04900f10f770fc24f7ce007af4c3be7a325ccc631","src/parser/locale.rs":"075c74803891894ad50bbedc69366931b8e76c0992b3caa1a5632f0a6816ccfd","src/parser/mod.rs":"5182392624876a419b1469d135d175aba680bb13d14e4f6ea0cfc4e071fbc743","src/serde.rs":"06e940e4f2d15f02d313b4e2b233aea3e74c93c6c43076f5ffe52d49c133608f","src/subtags/language.rs":"2ebc98952bd4a6b4077c77da1895225faacc17020af8a47675b8b41b05b9e7eb","src/subtags/mod.rs":"0257f746ed368ea3fa675054c9e7e40d972ec31cd7cc525be655a16a83c9d17b","src/subtags/region.rs":"4f4120f4910d0a4496f29c193d00313e71be4c646867d97ebd0e9a7438693847","src/subtags/script.rs":"6b1a68783cb90409bdd39b0184dfb2cb1c302fdee7202e3b6f7c7c8941bc7dfe","src/subtags/variant.rs":"956f1ea3d98172b6ead333411f010cf4e84404584a3051cb775d148d79beb4f8","src/subtags/variants.rs":"511aca7f5b75509b6b1b095e3465ab096430cc97b38e0bcb5956e71fa01c3189","src/zerovec.rs":"9d01a235d18296fbf0c2e89d188459e9446df0e63aaedc7e150165604af885b9","tests/fixtures/canonicalize.json":"9f2b7cbef72c24944cd4dc50de368c6e3ef69949f29c9ce1aa8807de767a4d0a","tests/fixtures/invalid-extensions.json":"4b7888006360b216030597257de8c301e22877e75216818967bbd8c83b6dbb0b","tests/fixtures/invalid.json":"5247849a6eb805619b8e70254c855227f7bdaf71431b071c91c6cc378ae9766e","tests/fixtures/langid.json":"960fd01722217ef1ea9077e2e0821d7089fe318a241bd7fb7918f50bf8f3f5c3","tests/fixtures/locale.json":"8606e0569fc6ea0e50a1fecb9295b911fbef7d8dbfde3c585476284a751baccf","tests/fixtures/mod.rs":"aea619960540b92199345cbd20ff03d2cb451aa2ce9aa6cf7915223ee9f812a3","tests/helpers/mod.rs":"d3bf59e7eed6230f340bef6c87a7b8de3a387ec391f60afc1b15a0d001cbfb67","tests/langid.rs":"43a0d381bdd9a8567898c137337a1563bea6db6fb36ecb853f496366faf8ff79","tests/locale.rs":"0cd3f09e83f6c093bca9676845612343a1e179d8584735e069008248e126eccf"},"package":"71d7a98ecb812760b5f077e55a4763edeefa7ccc30d6eb5680a70841ede81928"}
\ No newline at end of file diff --git a/vendor/icu_locid/Cargo.lock b/vendor/icu_locid/Cargo.lock index 9940858d2..401f5d44d 100644 --- a/vendor/icu_locid/Cargo.lock +++ b/vendor/icu_locid/Cargo.lock @@ -8,7 +8,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -39,9 +39,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "cast" @@ -131,26 +131,24 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.10" +version = "0.9.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", "memoffset", - "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.11" +version = "0.8.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" dependencies = [ "cfg-if", - "once_cell", ] [[package]] @@ -177,9 +175,9 @@ dependencies = [ [[package]] name = "databake" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87777d6d7bde863ba217aa87521dc857239de1f36d66aac46fd173fb0495858" +checksum = "df626c4717e455cd7a70a82c4358630554a07e4341f86dd095c625f1474a2857" dependencies = [ "databake-derive", "proc-macro2", @@ -189,9 +187,9 @@ dependencies = [ [[package]] name = "databake-derive" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "905c7a060fc0c84c0452d97473b1177dd7a5cbc7670cfbae4a7fe22e42f6432e" +checksum = "be51a53c468489ae1ef0efa9f6b10706f426c0dde06d66122ffef1f0c51e87dc" dependencies = [ "proc-macro2", "quote", @@ -232,26 +230,28 @@ dependencies = [ ] [[package]] -name = "iai" -version = "0.1.1" +name = "hermit-abi" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a816c97c42258aa5834d07590b718b4c9a598944cd39a52dc25b351185d678" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] [[package]] -name = "icu_benchmark_macros" -version = "0.7.0" +name = "iai" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c867656f2d9c90b13709ac88e710a9d6afe33998c1dfa22384bab8804e8b3d4" +checksum = "71a816c97c42258aa5834d07590b718b4c9a598944cd39a52dc25b351185d678" [[package]] name = "icu_locid" -version = "1.0.0" +version = "1.1.0" dependencies = [ "criterion", "databake", "displaydoc", "iai", - "icu_benchmark_macros", "litemap", "postcard", "serde", @@ -278,9 +278,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "js-sys" @@ -299,15 +299,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.133" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0f80d65747a3e43d1596c7c5492d95d5edddaabd45a7fcdb02b95f644164966" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "litemap" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34a3f4798fac63fb48cf277eefa38f94d3443baff555bb98e4f56bc9092368e" +checksum = "575d8a551c59104b4df91269921e5eab561aa1b77c618dac0414b5d44a4617de" [[package]] name = "log" @@ -326,9 +326,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] @@ -344,19 +344,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "oorandom" @@ -404,39 +404,37 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.44" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd7356a8122b6c4a24a82b278680c73357984ca2fc79a0f9fa6dea7dced7c58" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] [[package]] name = "rayon" -version = "1.5.3" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -446,9 +444,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "regex-syntax", ] @@ -461,15 +459,15 @@ checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "same-file" @@ -488,9 +486,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] @@ -507,9 +505,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -518,20 +516,20 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.85" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ - "itoa 1.0.3", + "itoa 1.0.5", "ryu", "serde", ] [[package]] name = "syn" -version = "1.0.101" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -561,9 +559,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8aeafdfd935e4a7fe16a91ab711fa52d54df84f9c8f7ca5837a9d1d902ef4c2" +checksum = "7ac3f5b6856e931e15e07b478e98c8045239829a65f9156d4fa7e7788197a5ef" dependencies = [ "displaydoc", "serde", @@ -581,9 +579,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-width" @@ -705,9 +703,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "writeable" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8e6ab4f5da1b24daf2c590cfac801bacb27b15b4f050e84eb60149ea726f06b" +checksum = "92d74a687e3b9a7a129db0a8c82b4d464eb9c36f5a66ca68572a7e5f1cfdb5bc" [[package]] name = "zerofrom" @@ -717,9 +715,9 @@ checksum = "79e9355fccf72b04b7deaa99ce7a0f6630530acf34045391b74460fcd714de54" [[package]] name = "zerovec" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d919a74c17749ccb17beaf6405562e413cd94e98ba52ca1e64bbe7eefbd8b8" +checksum = "154df60c74c4a844bc04a53cef4fc18a909d3ea07e19f5225eaba86209da3aa6" dependencies = [ "zerofrom", ] diff --git a/vendor/icu_locid/Cargo.toml b/vendor/icu_locid/Cargo.toml index 3ce7066e7..dbbe6ed2b 100644 --- a/vendor/icu_locid/Cargo.toml +++ b/vendor/icu_locid/Cargo.toml @@ -12,7 +12,7 @@ [package] edition = "2021" name = "icu_locid" -version = "1.0.0" +version = "1.1.0" authors = ["The ICU4X Project Developers"] include = [ "src/**/*", @@ -30,14 +30,12 @@ license = "Unicode-DFS-2016" repository = "https://github.com/unicode-org/icu4x" resolver = "2" -[package.metadata.cargo-all-features] -skip_optional_dependencies = true -denylist = ["bench"] -extra_features = ["serde"] - [package.metadata.docs.rs] all-features = true +[package.metadata.cargo-all-features] +denylist = ["bench"] + [lib] path = "src/lib.rs" bench = false @@ -69,7 +67,7 @@ harness = false required-features = ["bench"] [dependencies.databake] -version = "0.1.0" +version = "0.1.3" features = ["derive"] optional = true @@ -78,7 +76,7 @@ version = "0.2.3" default-features = false [dependencies.litemap] -version = "0.6" +version = "0.6.1" [dependencies.serde] version = "1.0" @@ -90,15 +88,15 @@ optional = true default-features = false [dependencies.tinystr] -version = "0.7" +version = "0.7.1" features = ["alloc"] default-features = false [dependencies.writeable] -version = "0.5" +version = "0.5.1" [dependencies.zerovec] -version = "0.9" +version = "0.9.2" optional = true [dev-dependencies.criterion] @@ -107,13 +105,6 @@ version = "0.3.3" [dev-dependencies.iai] version = "0.1.1" -[dev-dependencies.icu_benchmark_macros] -version = "0.7" - -[dev-dependencies.litemap] -version = "0.6" -features = ["testing"] - [dev-dependencies.postcard] version = "1.0.0" features = ["use-std"] @@ -128,9 +119,10 @@ version = "1.0" [features] bench = ["serde"] -default = [] +databake = ["dep:databake"] serde = [ "dep:serde", "tinystr/serde", ] std = [] +zerovec = ["dep:zerovec"] diff --git a/vendor/icu_locid/README.md b/vendor/icu_locid/README.md index cc2a0b023..5f49c35f5 100644 --- a/vendor/icu_locid/README.md +++ b/vendor/icu_locid/README.md @@ -20,36 +20,21 @@ If in doubt, use [`Locale`]. ## Examples ```rust -use icu::locid::subtags::{Language, Region}; use icu::locid::Locale; +use icu::locid::{ + locale, subtags_language as language, subtags_region as region, +}; -let mut loc: Locale = "en-US".parse().expect("Parsing failed."); - -let lang: Language = "en".parse().expect("Parsing failed."); -let region: Region = "US".parse().expect("Parsing failed."); +let mut loc: Locale = locale!("en-US"); -assert_eq!(loc.id.language, lang); +assert_eq!(loc.id.language, language!("en")); assert_eq!(loc.id.script, None); -assert_eq!(loc.id.region, Some(region)); +assert_eq!(loc.id.region, Some(region!("US"))); assert_eq!(loc.id.variants.len(), 0); -let region: Region = "GB".parse().expect("Parsing failed."); -loc.id.region = Some(region); - -assert_eq!(loc.to_string(), "en-GB"); -``` - -### Macros - -```rust -use icu::locid::{ - langid, subtags_language as language, subtags_region as region, -}; - -let lid = langid!("EN_US"); +loc.id.region = Some(region!("GB")); -assert_eq!(lid.language, language!("en")); -assert_eq!(lid.region, Some(region!("US"))); +assert_eq!(loc, locale!("en-GB")); ``` For more details, see [`Locale`] and [`LanguageIdentifier`]. diff --git a/vendor/icu_locid/benches/iai_langid.rs b/vendor/icu_locid/benches/iai_langid.rs index f964d1462..bf3b911cf 100644 --- a/vendor/icu_locid/benches/iai_langid.rs +++ b/vendor/icu_locid/benches/iai_langid.rs @@ -5,6 +5,7 @@ use icu_locid::{ langid, subtags_language as language, subtags_region as region, LanguageIdentifier, }; +use writeable::Writeable; const LIDS: &[LanguageIdentifier] = &[ langid!("en"), @@ -97,6 +98,12 @@ fn bench_langid_serialize() { let _: Vec<String> = LIDS.iter().map(|l| l.to_string()).collect(); } +fn bench_langid_serialize_writeable() { + // Tests serialization of LIDs. + + let _: Vec<_> = LIDS.iter().map(|l| l.write_to_string()).collect(); +} + fn bench_langid_canonicalize() { // Tests canonicalization of strings. @@ -114,5 +121,6 @@ iai::main!( bench_langid_matching, bench_langid_matching_str, bench_langid_serialize, + bench_langid_serialize_writeable, bench_langid_canonicalize, ); diff --git a/vendor/icu_locid/examples/filter_langids.rs b/vendor/icu_locid/examples/filter_langids.rs index 9e5b54e39..215df4eb3 100644 --- a/vendor/icu_locid/examples/filter_langids.rs +++ b/vendor/icu_locid/examples/filter_langids.rs @@ -16,6 +16,7 @@ icu_benchmark_macros::static_setup!(); use std::env; use icu_locid::{subtags, LanguageIdentifier}; +use writeable::Writeable; const DEFAULT_INPUT: &str = "de, en-us, zh-hant, sr-cyrl, fr-ca, es-cl, pl, en-latn-us, ca-valencia, und-arab"; @@ -30,7 +31,9 @@ fn filter_input(input: &str) -> String { let en_langids = langids.filter(|langid: &LanguageIdentifier| langid.language == en_lang); // 3. Serialize the output. - let en_strs: Vec<String> = en_langids.map(|langid| langid.to_string()).collect(); + let en_strs: Vec<String> = en_langids + .map(|langid| langid.write_to_string().into_owned()) + .collect(); en_strs.join(", ") } diff --git a/vendor/icu_locid/src/extensions/mod.rs b/vendor/icu_locid/src/extensions/mod.rs index 42bfcd3c9..a6a189b11 100644 --- a/vendor/icu_locid/src/extensions/mod.rs +++ b/vendor/icu_locid/src/extensions/mod.rs @@ -102,11 +102,11 @@ impl ExtensionType { #[derive(Debug, Default, PartialEq, Eq, Clone, Hash)] #[non_exhaustive] pub struct Extensions { - /// A representation of the data for a Unicode extension, when present in the locale identifer. + /// A representation of the data for a Unicode extension, when present in the locale identifier. pub unicode: Unicode, - /// A representation of the data for a transform extension, when present in the locale identifer. + /// A representation of the data for a transform extension, when present in the locale identifier. pub transform: Transform, - /// A representation of the data for a private-use extension, when present in the locale identifer. + /// A representation of the data for a private-use extension, when present in the locale identifier. pub private: Private, /// A sequence of any other extensions that are present in the locale identifier but are not formally /// [defined](https://unicode.org/reports/tr35/) and represented explicitly as [`Unicode`], [`Transform`], @@ -210,19 +210,33 @@ impl Extensions { let mut private = None; let mut other = Vec::new(); - let mut st = iter.next(); - while let Some(subtag) = st { + while let Some(subtag) = iter.next() { + if subtag.is_empty() { + return Err(ParserError::InvalidExtension); + } match subtag.get(0).map(|b| ExtensionType::try_from_byte(*b)) { Some(Ok(ExtensionType::Unicode)) => { + if unicode.is_some() { + return Err(ParserError::DuplicatedExtension); + } unicode = Some(Unicode::try_from_iter(iter)?); } Some(Ok(ExtensionType::Transform)) => { + if transform.is_some() { + return Err(ParserError::DuplicatedExtension); + } transform = Some(Transform::try_from_iter(iter)?); } Some(Ok(ExtensionType::Private)) => { + if private.is_some() { + return Err(ParserError::DuplicatedExtension); + } private = Some(Private::try_from_iter(iter)?); } Some(Ok(ExtensionType::Other(ext))) => { + if other.iter().any(|o: &Other| o.get_ext_byte() == ext) { + return Err(ParserError::DuplicatedExtension); + } let parsed = Other::try_from_iter(ext, iter)?; if let Err(idx) = other.binary_search(&parsed) { other.insert(idx, parsed); @@ -230,11 +244,8 @@ impl Extensions { return Err(ParserError::InvalidExtension); } } - None => {} _ => return Err(ParserError::InvalidExtension), } - - st = iter.next(); } Ok(Self { @@ -283,7 +294,7 @@ impl_writeable_for_each_subtag_str_no_test!(Extensions); fn test_writeable() { use crate::Locale; use writeable::assert_writeable_eq; - assert_writeable_eq!(Extensions::new(), "",); + assert_writeable_eq!(Extensions::new(), ""); assert_writeable_eq!( "my-t-my-d0-zawgyi".parse::<Locale>().unwrap().extensions, "t-my-d0-zawgyi", diff --git a/vendor/icu_locid/src/extensions/other/mod.rs b/vendor/icu_locid/src/extensions/other/mod.rs index 36dbc49b6..44d5c9cf8 100644 --- a/vendor/icu_locid/src/extensions/other/mod.rs +++ b/vendor/icu_locid/src/extensions/other/mod.rs @@ -41,13 +41,16 @@ pub use subtag::Subtag; /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// /// let other = Other::from_vec_unchecked(b'a', vec![subtag1, subtag2]); -/// assert_eq!(&other.to_string(), "-a-foo-bar"); +/// assert_eq!(&other.to_string(), "a-foo-bar"); /// ``` /// /// [`Other Use Extensions`]: https://unicode.org/reports/tr35/#other_extensions /// [`Unicode Locale Identifier`]: https://unicode.org/reports/tr35/#Unicode_locale_identifier #[derive(Clone, PartialEq, Eq, Debug, Default, Hash, PartialOrd, Ord)] -pub struct Other((u8, Vec<Subtag>)); +pub struct Other { + ext: u8, + keys: Vec<Subtag>, +} impl Other { /// A constructor which takes a pre-sorted list of [`Subtag`]. @@ -65,11 +68,11 @@ impl Other { /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// /// let other = Other::from_vec_unchecked(b'a', vec![subtag1, subtag2]); - /// assert_eq!(&other.to_string(), "-a-foo-bar"); + /// assert_eq!(&other.to_string(), "a-foo-bar"); /// ``` - pub fn from_vec_unchecked(ext: u8, input: Vec<Subtag>) -> Self { + pub fn from_vec_unchecked(ext: u8, keys: Vec<Subtag>) -> Self { assert!(ext.is_ascii_alphabetic()); - Self((ext, input)) + Self { ext, keys } } pub(crate) fn try_from_iter(ext: u8, iter: &mut SubtagIterator) -> Result<Self, ParserError> { @@ -89,6 +92,22 @@ impl Other { Ok(Self::from_vec_unchecked(ext, keys)) } + /// Gets the tag character for this extension as a &str. + /// + /// # Examples + /// + /// ``` + /// use icu::locid::Locale; + /// + /// let loc: Locale = "und-a-hello-world".parse().unwrap(); + /// let other_ext = &loc.extensions.other[0]; + /// assert_eq!(other_ext.get_ext_str(), "a"); + /// ``` + pub fn get_ext_str(&self) -> &str { + debug_assert!(self.ext.is_ascii_alphabetic()); + unsafe { core::str::from_utf8_unchecked(core::slice::from_ref(&self.ext)) } + } + /// Gets the tag character for this extension as a char. /// /// # Examples @@ -101,7 +120,7 @@ impl Other { /// assert_eq!(other_ext.get_ext(), 'a'); /// ``` pub fn get_ext(&self) -> char { - self.get_ext_byte() as char + self.ext as char } /// Gets the tag character for this extension as a byte. @@ -116,19 +135,15 @@ impl Other { /// assert_eq!(other_ext.get_ext_byte(), b'a'); /// ``` pub fn get_ext_byte(&self) -> u8 { - self.0 .0 + self.ext } pub(crate) fn for_each_subtag_str<E, F>(&self, f: &mut F) -> Result<(), E> where F: FnMut(&str) -> Result<(), E>, { - let (ext, keys) = &self.0; - debug_assert!(ext.is_ascii_alphabetic()); - // Safety: ext is ascii_alphabetic, so it is valid UTF-8 - let ext_str = unsafe { core::str::from_utf8_unchecked(core::slice::from_ref(ext)) }; - f(ext_str)?; - keys.iter().map(|t| t.as_str()).try_for_each(f) + f(self.get_ext_str())?; + self.keys.iter().map(|t| t.as_str()).try_for_each(f) } } @@ -136,10 +151,8 @@ writeable::impl_display_with_writeable!(Other); impl writeable::Writeable for Other { fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result { - let (ext, keys) = &self.0; - sink.write_char('-')?; - sink.write_char(*ext as char)?; - for key in keys.iter() { + sink.write_str(self.get_ext_str())?; + for key in self.keys.iter() { sink.write_char('-')?; writeable::Writeable::write_to(key, sink)?; } @@ -148,10 +161,20 @@ impl writeable::Writeable for Other { } fn writeable_length_hint(&self) -> writeable::LengthHint { - let mut result = writeable::LengthHint::exact(2); - for key in self.0 .1.iter() { + let mut result = writeable::LengthHint::exact(1); + for key in self.keys.iter() { result += writeable::Writeable::writeable_length_hint(key) + 1; } result } + + fn write_to_string(&self) -> alloc::borrow::Cow<str> { + if self.keys.is_empty() { + return alloc::borrow::Cow::Borrowed(self.get_ext_str()); + } + let mut string = + alloc::string::String::with_capacity(self.writeable_length_hint().capacity()); + let _ = self.write_to(&mut string); + alloc::borrow::Cow::Owned(string) + } } diff --git a/vendor/icu_locid/src/extensions/other/subtag.rs b/vendor/icu_locid/src/extensions/other/subtag.rs index 60995c395..ad4d6a0f2 100644 --- a/vendor/icu_locid/src/extensions/other/subtag.rs +++ b/vendor/icu_locid/src/extensions/other/subtag.rs @@ -11,11 +11,9 @@ impl_tinystr_subtag!( /// # Examples /// /// ``` - /// use icu::locid::extensions::other::Subtag; + /// use icu::locid::extensions_other_subtag as subtag; /// - /// let subtag: Subtag = "Foo".parse().expect("Failed to parse a Subtag."); - /// - /// assert_eq!(subtag.as_str(), "foo"); + /// assert_eq!(subtag!("Foo").as_str(), "foo"); /// ``` Subtag, extensions::other::Subtag, diff --git a/vendor/icu_locid/src/extensions/private/mod.rs b/vendor/icu_locid/src/extensions/private/mod.rs index 13090c94a..8382d166f 100644 --- a/vendor/icu_locid/src/extensions/private/mod.rs +++ b/vendor/icu_locid/src/extensions/private/mod.rs @@ -13,16 +13,18 @@ //! # Examples //! //! ``` -//! use icu::locid::extensions::private::{Private, Subtag}; -//! use icu::locid::Locale; +//! use icu::locid::extensions_private_subtag as subtag; +//! use icu::locid::{locale, Locale}; //! //! let mut loc: Locale = "en-US-x-foo-faa".parse().expect("Parsing failed."); //! -//! let subtag: Subtag = "foo".parse().expect("Parsing subtag failed."); -//! assert!(loc.extensions.private.contains(&subtag)); -//! assert_eq!(loc.extensions.private.iter().next(), Some(&subtag)); +//! assert!(loc.extensions.private.contains(&subtag!("foo"))); +//! assert_eq!(loc.extensions.private.iter().next(), Some(&subtag!("foo"))); +//! //! loc.extensions.private.clear(); -//! assert_eq!(loc.to_string(), "en-US"); +//! +//! assert!(loc.extensions.private.is_empty()); +//! assert_eq!(loc, locale!("en-US")); //! ``` mod other; @@ -50,7 +52,7 @@ use crate::parser::SubtagIterator; /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// /// let private = Private::from_vec_unchecked(vec![subtag1, subtag2]); -/// assert_eq!(&private.to_string(), "-x-foo-bar"); +/// assert_eq!(&private.to_string(), "x-foo-bar"); /// ``` /// /// [`Private Use Extensions`]: https://unicode.org/reports/tr35/#pu_extensions @@ -84,7 +86,7 @@ impl Private { /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// /// let private = Private::from_vec_unchecked(vec![subtag1, subtag2]); - /// assert_eq!(&private.to_string(), "-x-foo-bar"); + /// assert_eq!(&private.to_string(), "x-foo-bar"); /// ``` pub fn from_vec_unchecked(input: Vec<Subtag>) -> Self { Self(input) @@ -101,11 +103,11 @@ impl Private { /// let subtag2: Subtag = "bar".parse().expect("Failed to parse a Subtag."); /// let mut private = Private::from_vec_unchecked(vec![subtag1, subtag2]); /// - /// assert_eq!(&private.to_string(), "-x-foo-bar"); + /// assert_eq!(&private.to_string(), "x-foo-bar"); /// /// private.clear(); /// - /// assert_eq!(&private.to_string(), ""); + /// assert_eq!(private, Private::new()); /// ``` pub fn clear(&mut self) { self.0.clear(); @@ -138,7 +140,7 @@ impl writeable::Writeable for Private { if self.is_empty() { return Ok(()); } - sink.write_str("-x")?; + sink.write_str("x")?; for key in self.iter() { sink.write_char('-')?; writeable::Writeable::write_to(key, sink)?; @@ -150,7 +152,7 @@ impl writeable::Writeable for Private { if self.is_empty() { return writeable::LengthHint::exact(0); } - let mut result = writeable::LengthHint::exact(2); + let mut result = writeable::LengthHint::exact(1); for key in self.iter() { result += writeable::Writeable::writeable_length_hint(key) + 1; } diff --git a/vendor/icu_locid/src/extensions/transform/fields.rs b/vendor/icu_locid/src/extensions/transform/fields.rs index ca10000a7..f08581a87 100644 --- a/vendor/icu_locid/src/extensions/transform/fields.rs +++ b/vendor/icu_locid/src/extensions/transform/fields.rs @@ -25,10 +25,10 @@ use super::Value; /// /// ``` /// use icu::locid::extensions::transform::{Fields, Key, Value}; +/// use icu::locid::extensions_transform_key as key; /// -/// let key: Key = "h0".parse().expect("Failed to parse a Key."); -/// let value: Value = "hybrid".parse().expect("Failed to parse a Value."); -/// let fields: Fields = vec![(key, value)].into_iter().collect(); +/// let value = "hybrid".parse::<Value>().expect("Failed to parse a Value."); +/// let fields = vec![(key!("h0"), value)].into_iter().collect::<Fields>(); /// /// assert_eq!(&fields.to_string(), "h0-hybrid"); /// ``` @@ -76,17 +76,17 @@ impl Fields { /// # Examples /// /// ``` - /// use icu::locid::extensions::transform::{Fields, Key, Value}; + /// use icu::locid::extensions::transform::{Fields, Value}; + /// use icu::locid::extensions_transform_key as key; /// - /// let key: Key = "h0".parse().expect("Failed to parse a Key."); - /// let value: Value = "hybrid".parse().expect("Failed to parse a Value."); - /// let mut fields: Fields = vec![(key, value)].into_iter().collect(); + /// let value = "hybrid".parse::<Value>().expect("Failed to parse a Value."); + /// let mut fields = vec![(key!("h0"), value)].into_iter().collect::<Fields>(); /// /// assert_eq!(&fields.to_string(), "h0-hybrid"); /// /// fields.clear(); /// - /// assert_eq!(&fields.to_string(), ""); + /// assert_eq!(fields, Fields::new()); /// ``` pub fn clear(&mut self) -> Self { core::mem::take(self) @@ -122,16 +122,14 @@ impl Fields { /// /// ``` /// use icu::locid::extensions::transform::{Fields, Key, Value}; + /// use icu::locid::extensions_transform_key as key; /// - /// let key: Key = "h0".parse().expect("Failed to parse a Key."); - /// let value: Value = "hybrid".parse().expect("Failed to parse a Value."); - /// let mut fields: Fields = vec![(key, value)].into_iter().collect(); + /// let value = "hybrid".parse::<Value>().unwrap(); + /// let fields = vec![(key!("h0"), value.clone())] + /// .into_iter() + /// .collect::<Fields>(); /// - /// let key: Key = "h0".parse().expect("Failed to parse a Key."); - /// assert_eq!( - /// fields.get(&key).map(|v| v.to_string()), - /// Some("hybrid".to_string()) - /// ); + /// assert_eq!(fields.get(&key!("h0")), Some(&value)); /// ``` pub fn get<Q>(&self, key: &Q) -> Option<&Value> where diff --git a/vendor/icu_locid/src/extensions/transform/mod.rs b/vendor/icu_locid/src/extensions/transform/mod.rs index a8c605146..7b97d87f6 100644 --- a/vendor/icu_locid/src/extensions/transform/mod.rs +++ b/vendor/icu_locid/src/extensions/transform/mod.rs @@ -28,7 +28,7 @@ //! assert!(loc.extensions.transform.fields.contains_key(&key)); //! assert_eq!(loc.extensions.transform.fields.get(&key), Some(&value)); //! -//! assert_eq!(&loc.extensions.transform.to_string(), "-t-es-AR-h0-hybrid"); +//! assert_eq!(&loc.extensions.transform.to_string(), "t-es-AR-h0-hybrid"); //! ``` mod fields; mod key; @@ -208,7 +208,7 @@ impl writeable::Writeable for Transform { if self.is_empty() { return Ok(()); } - sink.write_str("-t")?; + sink.write_str("t")?; if let Some(lang) = &self.lang { sink.write_char('-')?; writeable::Writeable::write_to(lang, sink)?; @@ -224,7 +224,7 @@ impl writeable::Writeable for Transform { if self.is_empty() { return writeable::LengthHint::exact(0); } - let mut result = writeable::LengthHint::exact(2); + let mut result = writeable::LengthHint::exact(1); if let Some(lang) = &self.lang { result += writeable::Writeable::writeable_length_hint(lang) + 1; } diff --git a/vendor/icu_locid/src/extensions/transform/value.rs b/vendor/icu_locid/src/extensions/transform/value.rs index 84468361a..f908b0208 100644 --- a/vendor/icu_locid/src/extensions/transform/value.rs +++ b/vendor/icu_locid/src/extensions/transform/value.rs @@ -2,7 +2,7 @@ // called LICENSE at the top level of the ICU4X source tree // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). -use crate::parser::{get_subtag_iterator, ParserError}; +use crate::parser::{ParserError, SubtagIterator}; use alloc::vec; use alloc::vec::Vec; use core::ops::RangeInclusive; @@ -16,20 +16,18 @@ use tinystr::TinyAsciiStr; /// Each part of the sequence has to be no shorter than three characters and no /// longer than 8. /// -/// /// # Examples /// /// ``` /// use icu::locid::extensions::transform::Value; /// -/// let value1: Value = "hybrid".parse().expect("Failed to parse a Value."); -/// let value2: Value = -/// "hybrid-foobar".parse().expect("Failed to parse a Value."); +/// "hybrid".parse::<Value>().expect("Valid Value."); +/// +/// "hybrid-foobar".parse::<Value>().expect("Valid Value."); /// -/// assert_eq!(&value1.to_string(), "hybrid"); -/// assert_eq!(&value2.to_string(), "hybrid-foobar"); +/// "no".parse::<Value>().expect_err("Invalid Value."); /// ``` -#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Default)] pub struct Value(Vec<TinyAsciiStr<{ *TYPE_LENGTH.end() }>>); const TYPE_LENGTH: RangeInclusive<usize> = 3..=8; @@ -45,14 +43,12 @@ impl Value { /// use icu::locid::extensions::transform::Value; /// /// let value = Value::try_from_bytes(b"hybrid").expect("Parsing failed."); - /// - /// assert_eq!(&value.to_string(), "hybrid"); /// ``` pub fn try_from_bytes(input: &[u8]) -> Result<Self, ParserError> { let mut v = vec![]; let mut has_value = false; - for subtag in get_subtag_iterator(input) { + for subtag in SubtagIterator::new(input) { if !Self::is_type_subtag(subtag) { return Err(ParserError::InvalidExtension); } @@ -116,4 +112,19 @@ impl FromStr for Value { } } -impl_writeable_for_tinystr_list!(Value, "true", "hybrid", "foobar"); +impl_writeable_for_each_subtag_str_no_test!(Value, selff, selff.0.is_empty() => alloc::borrow::Cow::Borrowed("true")); + +#[test] +fn test_writeable() { + use writeable::assert_writeable_eq; + + let hybrid = "hybrid".parse().unwrap(); + let foobar = "foobar".parse().unwrap(); + + assert_writeable_eq!(Value::default(), "true"); + assert_writeable_eq!(Value::from_vec_unchecked(vec![hybrid]), "hybrid"); + assert_writeable_eq!( + Value::from_vec_unchecked(vec![hybrid, foobar]), + "hybrid-foobar" + ); +} diff --git a/vendor/icu_locid/src/extensions/unicode/attributes.rs b/vendor/icu_locid/src/extensions/unicode/attributes.rs index 1f9536bfa..e58fb04da 100644 --- a/vendor/icu_locid/src/extensions/unicode/attributes.rs +++ b/vendor/icu_locid/src/extensions/unicode/attributes.rs @@ -79,18 +79,19 @@ impl Attributes { /// /// ``` /// use icu::locid::extensions::unicode::{Attribute, Attributes}; + /// use icu::locid::extensions_unicode_attribute as attribute; + /// use writeable::assert_writeable_eq; /// - /// let attribute1: Attribute = "foobar".parse().expect("Parsing failed."); - /// let attribute2: Attribute = "testing".parse().expect("Parsing failed."); - /// let mut v = vec![attribute1, attribute2]; - /// - /// let mut attributes: Attributes = Attributes::from_vec_unchecked(v); + /// let mut attributes = Attributes::from_vec_unchecked(vec![ + /// attribute!("foobar"), + /// attribute!("testing"), + /// ]); /// - /// assert_eq!(attributes.to_string(), "foobar-testing"); + /// assert_writeable_eq!(attributes, "foobar-testing"); /// /// attributes.clear(); /// - /// assert_eq!(attributes.to_string(), ""); + /// assert_writeable_eq!(attributes, ""); /// ``` pub fn clear(&mut self) -> Self { core::mem::take(self) diff --git a/vendor/icu_locid/src/extensions/unicode/keywords.rs b/vendor/icu_locid/src/extensions/unicode/keywords.rs index dc9a15921..580cacaf1 100644 --- a/vendor/icu_locid/src/extensions/unicode/keywords.rs +++ b/vendor/icu_locid/src/extensions/unicode/keywords.rs @@ -29,11 +29,14 @@ use crate::ordering::SubtagOrderingResult; /// Manually build up a [`Keywords`] object: /// /// ``` -/// use icu::locid::extensions::unicode::{Key, Keywords, Value}; +/// use icu::locid::{ +/// extensions::unicode::Keywords, extensions_unicode_key as key, +/// extensions_unicode_value as value, locale, +/// }; /// -/// let key: Key = "hc".parse().expect("Failed to parse a Key."); -/// let value: Value = "h23".parse().expect("Failed to parse a Value."); -/// let keywords: Keywords = vec![(key, value)].into_iter().collect(); +/// let keywords = vec![(key!("hc"), value!("h23"))] +/// .into_iter() +/// .collect::<Keywords>(); /// /// assert_eq!(&keywords.to_string(), "hc-h23"); /// ``` @@ -113,15 +116,16 @@ impl Keywords { /// # Examples /// /// ``` - /// use icu::locid::extensions::unicode::{Key, Keywords, Value}; - /// use litemap::LiteMap; + /// use icu::locid::{ + /// extensions::unicode::Keywords, extensions_unicode_key as key, + /// extensions_unicode_value as value, + /// }; /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// let value: Value = "gregory".parse().expect("Failed to parse a Value."); - /// let keywords: Keywords = vec![(key, value)].into_iter().collect(); + /// let keywords = vec![(key!("ca"), value!("gregory"))] + /// .into_iter() + /// .collect::<Keywords>(); /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// assert!(&keywords.contains_key(&key)); + /// assert!(&keywords.contains_key(&key!("ca"))); /// ``` pub fn contains_key<Q>(&self, key: &Q) -> bool where @@ -137,17 +141,16 @@ impl Keywords { /// # Examples /// /// ``` - /// use icu::locid::extensions::unicode::{Key, Keywords, Value}; + /// use icu::locid::{ + /// extensions::unicode::Keywords, extensions_unicode_key as key, + /// extensions_unicode_value as value, + /// }; /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// let value: Value = "buddhist".parse().expect("Failed to parse a Value."); - /// let keywords: Keywords = vec![(key, value)].into_iter().collect(); + /// let keywords = vec![(key!("ca"), value!("buddhist"))] + /// .into_iter() + /// .collect::<Keywords>(); /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// assert_eq!( - /// keywords.get(&key).map(|v| v.to_string()), - /// Some("buddhist".to_string()) - /// ); + /// assert_eq!(keywords.get(&key!("ca")), Some(&value!("buddhist"))); /// ``` pub fn get<Q>(&self, key: &Q) -> Option<&Value> where @@ -164,20 +167,19 @@ impl Keywords { /// # Examples /// /// ``` - /// use icu::locid::extensions::unicode::{Key, Keywords, Value}; + /// use icu::locid::{ + /// extensions::unicode::Keywords, extensions_unicode_key as key, + /// extensions_unicode_value as value, + /// }; /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// let value: Value = "buddhist".parse().expect("Failed to parse a Value."); - /// let mut keywords: Keywords = vec![(key, value)].into_iter().collect(); + /// let mut keywords = vec![(key!("ca"), value!("buddhist"))] + /// .into_iter() + /// .collect::<Keywords>(); /// - /// let key: Key = "ca".parse().expect("Failed to parse a Key."); - /// if let Some(value) = keywords.get_mut(&key) { - /// *value = "gregory".parse().expect("Failed to parse a Value."); + /// if let Some(value) = keywords.get_mut(&key!("ca")) { + /// *value = value!("gregory"); /// } - /// assert_eq!( - /// keywords.get(&key).map(|v| v.to_string()), - /// Some("gregory".to_string()) - /// ); + /// assert_eq!(keywords.get(&key!("ca")), Some(&value!("gregory"))); /// ``` pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut Value> where @@ -308,7 +310,6 @@ impl Keywords { /// .extensions /// .unicode /// .keywords; - /// assert_eq!(a, a_kwds.to_string()); /// assert!(a_kwds.strict_cmp(a.as_bytes()) == Ordering::Equal); /// assert!(a_kwds.strict_cmp(b.as_bytes()) == Ordering::Less); /// } diff --git a/vendor/icu_locid/src/extensions/unicode/mod.rs b/vendor/icu_locid/src/extensions/unicode/mod.rs index fabf1036c..687a8c383 100644 --- a/vendor/icu_locid/src/extensions/unicode/mod.rs +++ b/vendor/icu_locid/src/extensions/unicode/mod.rs @@ -11,21 +11,24 @@ //! # Examples //! //! ``` -//! use icu::locid::extensions::unicode::{Attribute, Key, Unicode, Value}; -//! use icu::locid::{LanguageIdentifier, Locale}; +//! use icu::locid::Locale; +//! use icu::locid::{ +//! extensions::unicode::Unicode, +//! extensions_unicode_attribute as attribute, +//! extensions_unicode_key as key, extensions_unicode_value as value, +//! }; //! -//! let mut loc: Locale = -//! "en-US-u-foobar-hc-h12".parse().expect("Parsing failed."); +//! let loc: Locale = "en-US-u-foobar-hc-h12".parse().expect("Parsing failed."); //! -//! let key: Key = "hc".parse().expect("Parsing key failed."); -//! let value: Value = "h12".parse().expect("Parsing value failed."); -//! let attribute: Attribute = -//! "foobar".parse().expect("Parsing attribute failed."); -//! -//! assert_eq!(loc.extensions.unicode.keywords.get(&key), Some(&value)); -//! assert!(loc.extensions.unicode.attributes.contains(&attribute)); -//! -//! assert_eq!(&loc.extensions.unicode.to_string(), "-u-foobar-hc-h12"); +//! assert_eq!( +//! loc.extensions.unicode.keywords.get(&key!("hc")), +//! Some(&value!("h12")) +//! ); +//! assert!(loc +//! .extensions +//! .unicode +//! .attributes +//! .contains(&attribute!("foobar"))); //! ``` mod attribute; mod attributes; @@ -60,15 +63,18 @@ use litemap::LiteMap; /// # Examples /// /// ``` -/// use icu::locid::extensions::unicode::{Key, Value}; /// use icu::locid::Locale; +/// use icu::locid::{ +/// extensions_unicode_key as key, extensions_unicode_value as value, +/// }; /// -/// let mut loc: Locale = +/// let loc: Locale = /// "de-u-hc-h12-ca-buddhist".parse().expect("Parsing failed."); /// -/// let key: Key = "ca".parse().expect("Parsing key failed."); -/// let value: Value = "buddhist".parse().expect("Parsing value failed."); -/// assert_eq!(loc.extensions.unicode.keywords.get(&key), Some(&value)); +/// assert_eq!( +/// loc.extensions.unicode.keywords.get(&key!("ca")), +/// Some(&value!("buddhist")) +/// ); /// ``` #[derive(Clone, PartialEq, Eq, Debug, Default, Hash, PartialOrd, Ord)] #[allow(clippy::exhaustive_structs)] // spec-backed stable datastructure @@ -205,7 +211,7 @@ impl writeable::Writeable for Unicode { if self.is_empty() { return Ok(()); } - sink.write_str("-u")?; + sink.write_str("u")?; if !self.attributes.is_empty() { sink.write_char('-')?; writeable::Writeable::write_to(&self.attributes, sink)?; @@ -221,7 +227,7 @@ impl writeable::Writeable for Unicode { if self.is_empty() { return writeable::LengthHint::exact(0); } - let mut result = writeable::LengthHint::exact(2); + let mut result = writeable::LengthHint::exact(1); if !self.attributes.is_empty() { result += writeable::Writeable::writeable_length_hint(&self.attributes) + 1; } diff --git a/vendor/icu_locid/src/extensions/unicode/value.rs b/vendor/icu_locid/src/extensions/unicode/value.rs index ce9982a4c..e6374372c 100644 --- a/vendor/icu_locid/src/extensions/unicode/value.rs +++ b/vendor/icu_locid/src/extensions/unicode/value.rs @@ -3,7 +3,7 @@ // (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ). use crate::helpers::ShortVec; -use crate::parser::{get_subtag_iterator, ParserError}; +use crate::parser::{ParserError, SubtagIterator}; use alloc::vec::Vec; use core::ops::RangeInclusive; use core::str::FromStr; @@ -20,20 +20,21 @@ use tinystr::TinyAsciiStr; /// # Examples /// /// ``` -/// use icu::locid::extensions::unicode::Value; -/// -/// let value1: Value = "gregory".parse().expect("Failed to parse a Value."); -/// let value2: Value = -/// "islamic-civil".parse().expect("Failed to parse a Value."); -/// let value3: Value = "true".parse().expect("Failed to parse a Value."); +/// use icu::locid::{ +/// extensions::unicode::Value, extensions_unicode_value as value, +/// }; +/// use writeable::assert_writeable_eq; /// -/// assert_eq!(&value1.to_string(), "gregory"); -/// assert_eq!(&value2.to_string(), "islamic-civil"); +/// assert_writeable_eq!(value!("gregory"), "gregory"); +/// assert_writeable_eq!( +/// "islamic-civil".parse::<Value>().unwrap(), +/// "islamic-civil" +/// ); /// -/// // The value "true" is special-cased to an empty value -/// assert_eq!(&value3.to_string(), ""); +/// // The value "true" has the special, empty string representation +/// assert_eq!(value!("true").to_string(), ""); /// ``` -#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord)] +#[derive(Debug, PartialEq, Eq, Clone, Hash, PartialOrd, Ord, Default)] pub struct Value(ShortVec<TinyAsciiStr<{ *VALUE_LENGTH.end() }>>); const VALUE_LENGTH: RangeInclusive<usize> = 3..=8; @@ -48,15 +49,13 @@ impl Value { /// ``` /// use icu::locid::extensions::unicode::Value; /// - /// let value = Value::try_from_bytes(b"buddhist").expect("Parsing failed."); - /// - /// assert_eq!(&value.to_string(), "buddhist"); + /// Value::try_from_bytes(b"buddhist").expect("Parsing failed."); /// ``` pub fn try_from_bytes(input: &[u8]) -> Result<Self, ParserError> { let mut v = ShortVec::new(); if !input.is_empty() { - for subtag in get_subtag_iterator(input) { + for subtag in SubtagIterator::new(input) { let val = Self::subtag_from_bytes(subtag)?; if let Some(val) = val { v.push(val); @@ -153,7 +152,7 @@ impl FromStr for Value { } } -impl_writeable_for_tinystr_list!(Value, "", "islamic", "civil"); +impl_writeable_for_subtag_list!(Value, "islamic", "civil"); /// A macro allowing for compile-time construction of valid Unicode [`Value`] subtag. /// diff --git a/vendor/icu_locid/src/helpers.rs b/vendor/icu_locid/src/helpers.rs index e617ded5d..e5889a7b0 100644 --- a/vendor/icu_locid/src/helpers.rs +++ b/vendor/icu_locid/src/helpers.rs @@ -115,7 +115,7 @@ impl<T> ShortVec<T> { #[allow(clippy::unwrap_used)] // we know that the vec has exactly one element left 1 => (ShortVec::Single(v.pop().unwrap()), removed_item), - // v has atleast 2 elements, create a Multi variant + // v has at least 2 elements, create a Multi variant _ => (ShortVec::Multi(v), removed_item), } } @@ -387,6 +387,7 @@ macro_rules! impl_tinystr_subtag { } impl writeable::Writeable for $name { + #[inline] fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result { sink.write_str(self.as_str()) } @@ -394,6 +395,10 @@ macro_rules! impl_tinystr_subtag { fn writeable_length_hint(&self) -> writeable::LengthHint { writeable::LengthHint::exact(self.0.len()) } + #[inline] + fn write_to_string(&self) -> alloc::borrow::Cow<str> { + alloc::borrow::Cow::Borrowed(self.0.as_str()) + } } writeable::impl_display_with_writeable!($name); @@ -546,7 +551,7 @@ macro_rules! impl_tinystr_subtag { } macro_rules! impl_writeable_for_each_subtag_str_no_test { - ($type:tt) => { + ($type:tt $(, $self:ident, $borrow_cond:expr => $borrow:expr)?) => { impl writeable::Writeable for $type { fn write_to<W: core::fmt::Write + ?Sized>(&self, sink: &mut W) -> core::fmt::Result { let mut initial = true; @@ -576,6 +581,20 @@ macro_rules! impl_writeable_for_each_subtag_str_no_test { .expect("infallible"); result } + + $( + fn write_to_string(&self) -> alloc::borrow::Cow<str> { + #[allow(clippy::unwrap_used)] // impl_writeable_for_subtag_list's $borrow uses unwrap + let $self = self; + if $borrow_cond { + $borrow + } else { + let mut output = alloc::string::String::with_capacity(self.writeable_length_hint().capacity()); + let _ = self.write_to(&mut output); + alloc::borrow::Cow::Owned(output) + } + } + )? } writeable::impl_display_with_writeable!($type); @@ -584,7 +603,7 @@ macro_rules! impl_writeable_for_each_subtag_str_no_test { macro_rules! impl_writeable_for_subtag_list { ($type:tt, $sample1:literal, $sample2:literal) => { - impl_writeable_for_each_subtag_str_no_test!($type); + impl_writeable_for_each_subtag_str_no_test!($type, selff, selff.0.len() == 1 => alloc::borrow::Cow::Borrowed(selff.0.as_slice().get(0).unwrap().as_str())); #[test] fn test_writeable() { @@ -594,27 +613,6 @@ macro_rules! impl_writeable_for_subtag_list { $sample1, ); writeable::assert_writeable_eq!( - &$type::from_vec_unchecked(alloc::vec![ - $sample1.parse().unwrap(), - $sample2.parse().unwrap() - ]), - core::concat!($sample1, "-", $sample2), - ); - } - }; -} - -macro_rules! impl_writeable_for_tinystr_list { - ($type:tt, $if_empty:literal, $sample1:literal, $sample2:literal) => { - impl_writeable_for_each_subtag_str_no_test!($type); - - #[test] - fn test_writeable() { - writeable::assert_writeable_eq!( - &$type::from_vec_unchecked(vec![$sample1.parse().unwrap()]), - $sample1, - ); - writeable::assert_writeable_eq!( &$type::from_vec_unchecked(vec![ $sample1.parse().unwrap(), $sample2.parse().unwrap() diff --git a/vendor/icu_locid/src/langid.rs b/vendor/icu_locid/src/langid.rs index fc5435766..b6858c91b 100644 --- a/vendor/icu_locid/src/langid.rs +++ b/vendor/icu_locid/src/langid.rs @@ -7,27 +7,28 @@ use core::str::FromStr; use crate::ordering::SubtagOrderingResult; use crate::parser::{ - get_subtag_iterator, parse_language_identifier, parse_language_identifier_with_single_variant, - ParserError, ParserMode, + parse_language_identifier, parse_language_identifier_with_single_variant, ParserError, + ParserMode, SubtagIterator, }; use crate::subtags; use alloc::string::String; -use alloc::string::ToString; +use writeable::Writeable; /// A core struct representing a [`Unicode BCP47 Language Identifier`]. /// /// # Examples /// /// ``` -/// use icu::locid::{subtags::*, LanguageIdentifier}; +/// use icu::locid::{ +/// langid, subtags_language as language, subtags_region as region, +/// }; /// -/// let li: LanguageIdentifier = "en-US".parse().expect("Failed to parse."); +/// let li = langid!("en-US"); /// -/// assert_eq!(li.language, "en".parse::<Language>().unwrap()); +/// assert_eq!(li.language, language!("en")); /// assert_eq!(li.script, None); -/// assert_eq!(li.region.unwrap(), "US".parse::<Region>().unwrap()); +/// assert_eq!(li.region, Some(region!("US"))); /// assert_eq!(li.variants.len(), 0); -/// assert_eq!(li.to_string(), "en-US"); /// ``` /// /// # Parsing @@ -47,18 +48,17 @@ use alloc::string::ToString; /// # Examples /// /// ``` -/// use icu::locid::{subtags::*, LanguageIdentifier}; +/// use icu::locid::{ +/// langid, subtags_language as language, subtags_region as region, +/// subtags_script as script, subtags_variant as variant, +/// }; /// -/// let li: LanguageIdentifier = -/// "eN_latn_Us-Valencia".parse().expect("Failed to parse."); +/// let li = langid!("eN_latn_Us-Valencia"); /// -/// assert_eq!(li.language, "en".parse::<Language>().unwrap()); -/// assert_eq!(li.script, "Latn".parse::<Script>().ok()); -/// assert_eq!(li.region, "US".parse::<Region>().ok()); -/// assert_eq!( -/// li.variants.get(0), -/// "valencia".parse::<Variant>().ok().as_ref() -/// ); +/// assert_eq!(li.language, language!("en")); +/// assert_eq!(li.script, Some(script!("Latn"))); +/// assert_eq!(li.region, Some(region!("US"))); +/// assert_eq!(li.variants.get(0), Some(&variant!("valencia"))); /// ``` /// /// [`Unicode BCP47 Language Identifier`]: https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier @@ -84,10 +84,7 @@ impl LanguageIdentifier { /// ``` /// use icu::locid::LanguageIdentifier; /// - /// let li = - /// LanguageIdentifier::try_from_bytes(b"en-US").expect("Parsing failed."); - /// - /// assert_eq!(li.to_string(), "en-US"); + /// LanguageIdentifier::try_from_bytes(b"en-US").expect("Parsing failed"); /// ``` pub fn try_from_bytes(v: &[u8]) -> Result<Self, ParserError> { parse_language_identifier(v, ParserMode::LanguageIdentifier) @@ -117,12 +114,12 @@ impl LanguageIdentifier { /// # Examples /// /// ``` - /// use icu::locid::LanguageIdentifier; + /// use icu::locid::{langid, LanguageIdentifier}; /// /// let li = LanguageIdentifier::try_from_locale_bytes(b"en-US-x-posix") /// .expect("Parsing failed."); /// - /// assert_eq!(li.to_string(), "en-US"); + /// assert_eq!(li, langid!("en-US")); /// ``` /// /// This method should be used for input that may be a locale identifier. @@ -139,7 +136,6 @@ impl LanguageIdentifier { /// use icu::locid::LanguageIdentifier; /// /// assert_eq!(LanguageIdentifier::default(), LanguageIdentifier::UND); - /// assert_eq!("und", LanguageIdentifier::UND.to_string()); /// ``` pub const UND: Self = Self { language: subtags::Language::UND, @@ -159,13 +155,13 @@ impl LanguageIdentifier { /// use icu::locid::LanguageIdentifier; /// /// assert_eq!( - /// LanguageIdentifier::canonicalize("pL_latn_pl"), - /// Ok("pl-Latn-PL".to_string()) + /// LanguageIdentifier::canonicalize("pL_latn_pl").as_deref(), + /// Ok("pl-Latn-PL") /// ); /// ``` pub fn canonicalize<S: AsRef<[u8]>>(input: S) -> Result<String, ParserError> { let lang_id = Self::try_from_bytes(input.as_ref())?; - Ok(lang_id.to_string()) + Ok(lang_id.write_to_string().into_owned()) } /// Compare this [`LanguageIdentifier`] with BCP-47 bytes. @@ -197,7 +193,6 @@ impl LanguageIdentifier { /// let b = ab[1]; /// assert!(a.cmp(b) == Ordering::Less); /// let a_langid = a.parse::<LanguageIdentifier>().unwrap(); - /// assert_eq!(a, a_langid.to_string()); /// assert!(a_langid.strict_cmp(a.as_bytes()) == Ordering::Equal); /// assert!(a_langid.strict_cmp(b.as_bytes()) == Ordering::Less); /// } @@ -293,7 +288,7 @@ impl LanguageIdentifier { }; } - let mut iter = get_subtag_iterator(other.as_bytes()); + let mut iter = SubtagIterator::new(other.as_bytes()); if !subtag_matches!(subtags::Language, iter, self.language) { return false; } @@ -359,7 +354,7 @@ impl FromStr for LanguageIdentifier { } } -impl_writeable_for_each_subtag_str_no_test!(LanguageIdentifier); +impl_writeable_for_each_subtag_str_no_test!(LanguageIdentifier, selff, selff.script.is_none() && selff.region.is_none() && selff.variants.is_empty() => selff.language.write_to_string()); #[test] fn test_writeable() { @@ -387,14 +382,11 @@ fn test_writeable() { /// # Examples /// /// ``` -/// use icu::locid::subtags_language as language; -/// use icu::locid::LanguageIdentifier; -/// -/// let language = language!("en"); -/// let li = LanguageIdentifier::from(language); +/// use icu::locid::{ +/// langid, subtags_language as language, LanguageIdentifier, +/// }; /// -/// assert_eq!(li.language, language); -/// assert_eq!(li.to_string(), "en"); +/// assert_eq!(LanguageIdentifier::from(language!("en")), langid!("en")); /// ``` impl From<subtags::Language> for LanguageIdentifier { fn from(language: subtags::Language) -> Self { @@ -408,14 +400,12 @@ impl From<subtags::Language> for LanguageIdentifier { /// # Examples /// /// ``` -/// use icu::locid::subtags_script as script; -/// use icu::locid::LanguageIdentifier; +/// use icu::locid::{langid, subtags_script as script, LanguageIdentifier}; /// -/// let script = script!("latn"); -/// let li = LanguageIdentifier::from(Some(script)); -/// -/// assert_eq!(li.script.unwrap(), script); -/// assert_eq!(li.to_string(), "und-Latn"); +/// assert_eq!( +/// LanguageIdentifier::from(Some(script!("latn"))), +/// langid!("und-Latn") +/// ); /// ``` impl From<Option<subtags::Script>> for LanguageIdentifier { fn from(script: Option<subtags::Script>) -> Self { @@ -429,14 +419,12 @@ impl From<Option<subtags::Script>> for LanguageIdentifier { /// # Examples /// /// ``` -/// use icu::locid::subtags_region as region; -/// use icu::locid::LanguageIdentifier; +/// use icu::locid::{langid, subtags_region as region, LanguageIdentifier}; /// -/// let region = region!("US"); -/// let li = LanguageIdentifier::from(Some(region)); -/// -/// assert_eq!(li.region.unwrap(), region); -/// assert_eq!(li.to_string(), "und-US"); +/// assert_eq!( +/// LanguageIdentifier::from(Some(region!("US"))), +/// langid!("und-US") +/// ); /// ``` impl From<Option<subtags::Region>> for LanguageIdentifier { fn from(region: Option<subtags::Region>) -> Self { @@ -452,22 +440,18 @@ impl From<Option<subtags::Region>> for LanguageIdentifier { /// # Examples /// /// ``` -/// use icu::locid::LanguageIdentifier; /// use icu::locid::{ -/// subtags_language as language, subtags_region as region, -/// subtags_script as script, +/// langid, subtags_language as language, subtags_region as region, +/// subtags_script as script, LanguageIdentifier, /// }; /// /// let lang = language!("en"); /// let script = script!("Latn"); /// let region = region!("US"); -/// let li = LanguageIdentifier::from((lang, Some(script), Some(region))); -/// -/// assert_eq!(li.language, lang); -/// assert_eq!(li.script.unwrap(), script); -/// assert_eq!(li.region.unwrap(), region); -/// assert_eq!(li.variants.len(), 0); -/// assert_eq!(li.to_string(), "en-Latn-US"); +/// assert_eq!( +/// LanguageIdentifier::from((lang, Some(script), Some(region))), +/// langid!("en-Latn-US") +/// ); /// ``` impl From<( @@ -497,7 +481,6 @@ impl /// # Examples /// /// ``` -/// use icu::locid::LanguageIdentifier; /// use icu::locid::{ /// langid, subtags_language as language, subtags_region as region, /// subtags_script as script, diff --git a/vendor/icu_locid/src/lib.rs b/vendor/icu_locid/src/lib.rs index 885c4b743..226a8e53c 100644 --- a/vendor/icu_locid/src/lib.rs +++ b/vendor/icu_locid/src/lib.rs @@ -22,39 +22,23 @@ //! # Examples //! //! ``` -//! use icu::locid::subtags::{Language, Region}; //! use icu::locid::Locale; +//! use icu::locid::{ +//! locale, subtags_language as language, subtags_region as region, +//! }; //! -//! let mut loc: Locale = "en-US".parse().expect("Parsing failed."); -//! -//! let lang: Language = "en".parse().expect("Parsing failed."); -//! let region: Region = "US".parse().expect("Parsing failed."); +//! let mut loc: Locale = locale!("en-US"); //! -//! assert_eq!(loc.id.language, lang); +//! assert_eq!(loc.id.language, language!("en")); //! assert_eq!(loc.id.script, None); -//! assert_eq!(loc.id.region, Some(region)); +//! assert_eq!(loc.id.region, Some(region!("US"))); //! assert_eq!(loc.id.variants.len(), 0); //! -//! let region: Region = "GB".parse().expect("Parsing failed."); -//! loc.id.region = Some(region); +//! loc.id.region = Some(region!("GB")); //! -//! assert_eq!(loc.to_string(), "en-GB"); +//! assert_eq!(loc, locale!("en-GB")); //! ``` //! -//! ## Macros -//! -//! ```rust -//! use icu::locid::{ -//! langid, subtags_language as language, subtags_region as region, -//! }; -//! -//! let lid = langid!("EN_US"); -//! -//! assert_eq!(lid.language, language!("en")); -//! assert_eq!(lid.region, Some(region!("US"))); -//! ``` - -//! //! For more details, see [`Locale`] and [`LanguageIdentifier`]. //! //! [`UTS #35: Unicode LDML 3. Unicode Language and Locale Identifiers`]: https://unicode.org/reports/tr35/tr35.html#Unicode_Language_and_Locale_Identifiers diff --git a/vendor/icu_locid/src/locale.rs b/vendor/icu_locid/src/locale.rs index d7040d31a..5d9109fee 100644 --- a/vendor/icu_locid/src/locale.rs +++ b/vendor/icu_locid/src/locale.rs @@ -4,16 +4,15 @@ use crate::ordering::SubtagOrderingResult; use crate::parser::{ - get_subtag_iterator, parse_locale, - parse_locale_with_single_variant_single_keyword_unicode_keyword_extension, ParserError, - ParserMode, + parse_locale, parse_locale_with_single_variant_single_keyword_unicode_keyword_extension, + ParserError, ParserMode, SubtagIterator, }; use crate::{extensions, subtags, LanguageIdentifier}; use alloc::string::String; -use alloc::string::ToString; use core::cmp::Ordering; use core::str::FromStr; use tinystr::TinyAsciiStr; +use writeable::Writeable; /// A core struct representing a [`Unicode Locale Identifier`]. /// @@ -28,20 +27,21 @@ use tinystr::TinyAsciiStr; /// # Examples /// /// ``` -/// use icu::locid::extensions::unicode::{Key, Value}; -/// use icu::locid::{subtags::*, Locale}; +/// use icu_locid::{ +/// extensions_unicode_key as key, extensions_unicode_value as value, +/// locale, subtags_language as language, subtags_region as region, +/// }; /// -/// let loc: Locale = "en-US-u-ca-buddhist".parse().expect("Failed to parse."); +/// let loc = locale!("en-US-u-ca-buddhist"); /// -/// assert_eq!(loc.id.language, "en".parse::<Language>().unwrap()); +/// assert_eq!(loc.id.language, language!("en")); /// assert_eq!(loc.id.script, None); -/// assert_eq!(loc.id.region, "US".parse::<Region>().ok()); +/// assert_eq!(loc.id.region, Some(region!("US"))); /// assert_eq!(loc.id.variants.len(), 0); -/// assert_eq!(loc.to_string(), "en-US-u-ca-buddhist"); -/// -/// let key: Key = "ca".parse().expect("Parsing key failed."); -/// let value: Value = "buddhist".parse().expect("Parsing value failed."); -/// assert_eq!(loc.extensions.unicode.keywords.get(&key), Some(&value)); +/// assert_eq!( +/// loc.extensions.unicode.keywords.get(&key!("ca")), +/// Some(&value!("buddhist")) +/// ); /// ``` /// /// # Parsing @@ -87,6 +87,8 @@ pub struct Locale { #[test] fn test_sizes() { + // Remove when we upgrade to a compiler where the new sizes are default + let forced_nightly = std::env::var("ICU4X_BUILDING_WITH_FORCED_NIGHTLY").is_ok(); assert_eq!(core::mem::size_of::<subtags::Language>(), 3); assert_eq!(core::mem::size_of::<subtags::Script>(), 4); assert_eq!(core::mem::size_of::<subtags::Region>(), 3); @@ -99,12 +101,21 @@ fn test_sizes() { assert_eq!(core::mem::size_of::<extensions::transform::Fields>(), 24); assert_eq!(core::mem::size_of::<extensions::unicode::Attributes>(), 24); - assert_eq!(core::mem::size_of::<extensions::unicode::Keywords>(), 48); + assert_eq!( + core::mem::size_of::<extensions::unicode::Keywords>(), + if forced_nightly { 40 } else { 48 } + ); assert_eq!(core::mem::size_of::<Vec<extensions::other::Other>>(), 24); assert_eq!(core::mem::size_of::<extensions::private::Private>(), 24); - assert_eq!(core::mem::size_of::<extensions::Extensions>(), 192); + assert_eq!( + core::mem::size_of::<extensions::Extensions>(), + if forced_nightly { 184 } else { 192 } + ); - assert_eq!(core::mem::size_of::<Locale>(), 240); + assert_eq!( + core::mem::size_of::<Locale>(), + if forced_nightly { 232 } else { 240 } + ); } impl Locale { @@ -116,10 +127,7 @@ impl Locale { /// ``` /// use icu::locid::Locale; /// - /// let loc = Locale::try_from_bytes("en-US-u-hc-h12".as_bytes()) - /// .expect("Parsing failed."); - /// - /// assert_eq!(loc.to_string(), "en-US-u-hc-h12"); + /// Locale::try_from_bytes(b"en-US-u-hc-h12").unwrap(); /// ``` pub fn try_from_bytes(v: &[u8]) -> Result<Self, ParserError> { parse_locale(v) @@ -133,7 +141,6 @@ impl Locale { /// use icu::locid::Locale; /// /// assert_eq!(Locale::default(), Locale::UND); - /// assert_eq!("und", Locale::UND.to_string()); /// ``` pub const UND: Self = Self { id: LanguageIdentifier::UND, @@ -151,13 +158,13 @@ impl Locale { /// use icu::locid::Locale; /// /// assert_eq!( - /// Locale::canonicalize("pL_latn_pl-U-HC-H12"), - /// Ok("pl-Latn-PL-u-hc-h12".to_string()) + /// Locale::canonicalize("pL_latn_pl-U-HC-H12").as_deref(), + /// Ok("pl-Latn-PL-u-hc-h12") /// ); /// ``` pub fn canonicalize<S: AsRef<[u8]>>(input: S) -> Result<String, ParserError> { let locale = Self::try_from_bytes(input.as_ref())?; - Ok(locale.to_string()) + Ok(locale.write_to_string().into_owned()) } /// Compare this [`Locale`] with BCP-47 bytes. @@ -189,7 +196,6 @@ impl Locale { /// let b = ab[1]; /// assert!(a.cmp(b) == Ordering::Less); /// let a_loc = a.parse::<Locale>().unwrap(); - /// assert_eq!(a, a_loc.to_string()); /// assert!(a_loc.strict_cmp(a.as_bytes()) == Ordering::Equal); /// assert!(a_loc.strict_cmp(b.as_bytes()) == Ordering::Less); /// } @@ -286,7 +292,7 @@ impl Locale { }; } - let mut iter = get_subtag_iterator(other.as_bytes()); + let mut iter = SubtagIterator::new(other.as_bytes()); if !subtag_matches!(subtags::Language, iter, self.id.language) { return false; } @@ -391,7 +397,7 @@ impl core::fmt::Debug for Locale { } } -impl_writeable_for_each_subtag_str_no_test!(Locale); +impl_writeable_for_each_subtag_str_no_test!(Locale, selff, selff.extensions.is_empty() => selff.id.write_to_string()); #[test] fn test_writeable() { @@ -426,14 +432,10 @@ fn test_writeable() { /// # Examples /// /// ``` -/// use icu::locid::subtags_language as language; /// use icu::locid::Locale; +/// use icu::locid::{locale, subtags_language as language}; /// -/// let language = language!("en"); -/// let loc = Locale::from(language); -/// -/// assert_eq!(loc.id.language, language); -/// assert_eq!(loc.to_string(), "en"); +/// assert_eq!(Locale::from(language!("en")), locale!("en")); /// ``` impl From<subtags::Language> for Locale { fn from(language: subtags::Language) -> Self { @@ -447,14 +449,10 @@ impl From<subtags::Language> for Locale { /// # Examples /// /// ``` -/// use icu::locid::subtags_script as script; /// use icu::locid::Locale; +/// use icu::locid::{locale, subtags_script as script}; /// -/// let script = script!("latn"); -/// let loc = Locale::from(Some(script)); -/// -/// assert_eq!(loc.id.script.unwrap(), script); -/// assert_eq!(loc.to_string(), "und-Latn"); +/// assert_eq!(Locale::from(Some(script!("latn"))), locale!("und-Latn")); /// ``` impl From<Option<subtags::Script>> for Locale { fn from(script: Option<subtags::Script>) -> Self { @@ -468,14 +466,10 @@ impl From<Option<subtags::Script>> for Locale { /// # Examples /// /// ``` -/// use icu::locid::subtags_region as region; /// use icu::locid::Locale; +/// use icu::locid::{locale, subtags_region as region}; /// -/// let region = region!("US"); -/// let loc = Locale::from(Some(region)); -/// -/// assert_eq!(loc.id.region.unwrap(), region); -/// assert_eq!(loc.to_string(), "und-US"); +/// assert_eq!(Locale::from(Some(region!("US"))), locale!("und-US")); /// ``` impl From<Option<subtags::Region>> for Locale { fn from(region: Option<subtags::Region>) -> Self { @@ -491,20 +485,18 @@ impl From<Option<subtags::Region>> for Locale { /// ``` /// use icu::locid::Locale; /// use icu::locid::{ -/// subtags_language as language, subtags_region as region, +/// locale, subtags_language as language, subtags_region as region, /// subtags_script as script, /// }; /// -/// let lang = language!("en"); -/// let script = script!("Latn"); -/// let region = region!("US"); -/// let loc = Locale::from((lang, Some(script), Some(region))); -/// -/// assert_eq!(loc.id.language, lang); -/// assert_eq!(loc.id.script.unwrap(), script); -/// assert_eq!(loc.id.region.unwrap(), region); -/// assert_eq!(loc.id.variants.len(), 0); -/// assert_eq!(loc.to_string(), "en-Latn-US"); +/// assert_eq!( +/// Locale::from(( +/// language!("en"), +/// Some(script!("Latn")), +/// Some(region!("US")) +/// )), +/// locale!("en-Latn-US") +/// ); /// ``` impl From<( diff --git a/vendor/icu_locid/src/parser/errors.rs b/vendor/icu_locid/src/parser/errors.rs index a989bcc60..5cbbb2bd4 100644 --- a/vendor/icu_locid/src/parser/errors.rs +++ b/vendor/icu_locid/src/parser/errors.rs @@ -48,6 +48,22 @@ pub enum ParserError { /// ``` #[displaydoc("Invalid extension")] InvalidExtension, + + /// Duplicated extension. + /// + /// # Examples + /// + /// ``` + /// use icu::locid::Locale; + /// use icu::locid::ParserError; + /// + /// assert_eq!( + /// "und-u-hc-h12-u-ca-calendar".parse::<Locale>(), + /// Err(ParserError::DuplicatedExtension) + /// ); + /// ``` + #[displaydoc("Duplicated extension")] + DuplicatedExtension, } #[cfg(feature = "std")] diff --git a/vendor/icu_locid/src/parser/langid.rs b/vendor/icu_locid/src/parser/langid.rs index 9efa078ac..653ca7e6e 100644 --- a/vendor/icu_locid/src/parser/langid.rs +++ b/vendor/icu_locid/src/parser/langid.rs @@ -5,7 +5,7 @@ pub use super::errors::ParserError; use crate::extensions::unicode::{Attribute, Key, Value}; use crate::extensions::ExtensionType; -use crate::parser::{get_subtag_iterator, SubtagIterator}; +use crate::parser::SubtagIterator; use crate::LanguageIdentifier; use crate::{extensions, subtags}; use alloc::vec::Vec; @@ -103,7 +103,7 @@ pub fn parse_language_identifier( t: &[u8], mode: ParserMode, ) -> Result<LanguageIdentifier, ParserError> { - let mut iter = get_subtag_iterator(t); + let mut iter = SubtagIterator::new(t); parse_language_identifier_from_iter(&mut iter, mode) } @@ -127,9 +127,9 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_extension_f let mut variant = None; let mut keyword = None; - if let (i, Some((t, start, end))) = iter.next_manual() { + if let (i, Some((start, end))) = iter.next_manual() { iter = i; - match subtags::Language::try_from_bytes_manual_slice(t, start, end) { + match subtags::Language::try_from_bytes_manual_slice(iter.slice, start, end) { Ok(l) => language = l, Err(e) => return Err(e), } @@ -139,19 +139,23 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_extension_f let mut position = ParserPosition::Script; - while let Some((t, start, end)) = iter.peek_manual() { + while let Some((start, end)) = iter.peek_manual() { if !matches!(mode, ParserMode::LanguageIdentifier) && end - start == 1 { break; } if matches!(position, ParserPosition::Script) { - if let Ok(s) = subtags::Script::try_from_bytes_manual_slice(t, start, end) { + if let Ok(s) = subtags::Script::try_from_bytes_manual_slice(iter.slice, start, end) { script = Some(s); position = ParserPosition::Region; - } else if let Ok(r) = subtags::Region::try_from_bytes_manual_slice(t, start, end) { + } else if let Ok(r) = + subtags::Region::try_from_bytes_manual_slice(iter.slice, start, end) + { region = Some(r); position = ParserPosition::Variant; - } else if let Ok(v) = subtags::Variant::try_from_bytes_manual_slice(t, start, end) { + } else if let Ok(v) = + subtags::Variant::try_from_bytes_manual_slice(iter.slice, start, end) + { // We cannot handle multiple variants in a const context debug_assert!(variant.is_none()); variant = Some(v); @@ -162,10 +166,12 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_extension_f return Err(ParserError::InvalidSubtag); } } else if matches!(position, ParserPosition::Region) { - if let Ok(s) = subtags::Region::try_from_bytes_manual_slice(t, start, end) { + if let Ok(s) = subtags::Region::try_from_bytes_manual_slice(iter.slice, start, end) { region = Some(s); position = ParserPosition::Variant; - } else if let Ok(v) = subtags::Variant::try_from_bytes_manual_slice(t, start, end) { + } else if let Ok(v) = + subtags::Variant::try_from_bytes_manual_slice(iter.slice, start, end) + { // We cannot handle multiple variants in a const context debug_assert!(variant.is_none()); variant = Some(v); @@ -175,7 +181,8 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_extension_f } else { return Err(ParserError::InvalidSubtag); } - } else if let Ok(v) = subtags::Variant::try_from_bytes_manual_slice(t, start, end) { + } else if let Ok(v) = subtags::Variant::try_from_bytes_manual_slice(iter.slice, start, end) + { debug_assert!(matches!(position, ParserPosition::Variant)); if variant.is_some() { // We cannot handle multiple variants in a const context @@ -192,12 +199,12 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_extension_f } if matches!(mode, ParserMode::Locale) { - if let Some((bytes, start, end)) = iter.peek_manual() { - match ExtensionType::try_from_bytes_manual_slice(bytes, start, end) { + if let Some((start, end)) = iter.peek_manual() { + match ExtensionType::try_from_bytes_manual_slice(iter.slice, start, end) { Ok(ExtensionType::Unicode) => { iter = iter.next_manual().0; - if let Some((bytes, start, end)) = iter.peek_manual() { - if Attribute::try_from_bytes_manual_slice(bytes, start, end).is_ok() { + if let Some((start, end)) = iter.peek_manual() { + if Attribute::try_from_bytes_manual_slice(iter.slice, start, end).is_ok() { // We cannot handle Attributes in a const context return Err(ParserError::InvalidSubtag); } @@ -206,19 +213,21 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_extension_f let mut key = None; let mut current_type = None; - while let Some((bytes, start, end)) = iter.peek_manual() { + while let Some((start, end)) = iter.peek_manual() { let slen = end - start; if slen == 2 { if key.is_some() { // We cannot handle more than one Key in a const context return Err(ParserError::InvalidSubtag); } - match Key::try_from_bytes_manual_slice(bytes, start, end) { + match Key::try_from_bytes_manual_slice(iter.slice, start, end) { Ok(k) => key = Some(k), Err(e) => return Err(e), }; } else if key.is_some() { - match Value::parse_subtag_from_bytes_manual_slice(bytes, start, end) { + match Value::parse_subtag_from_bytes_manual_slice( + iter.slice, start, end, + ) { Ok(Some(t)) => { if current_type.is_some() { // We cannot handle more than one type in a const context @@ -261,7 +270,7 @@ pub const fn parse_language_identifier_with_single_variant( ), ParserError, > { - let iter = get_subtag_iterator(t); + let iter = SubtagIterator::new(t); match parse_locale_with_single_variant_single_keyword_unicode_extension_from_iter(iter, mode) { Ok((l, s, r, v, _)) => Ok((l, s, r, v)), Err(e) => Err(e), diff --git a/vendor/icu_locid/src/parser/locale.rs b/vendor/icu_locid/src/parser/locale.rs index 805b6c290..175fd3a05 100644 --- a/vendor/icu_locid/src/parser/locale.rs +++ b/vendor/icu_locid/src/parser/locale.rs @@ -6,13 +6,13 @@ use tinystr::TinyAsciiStr; use crate::extensions::{self, Extensions}; use crate::parser::errors::ParserError; -use crate::parser::{get_subtag_iterator, parse_language_identifier_from_iter, ParserMode}; +use crate::parser::{parse_language_identifier_from_iter, ParserMode, SubtagIterator}; use crate::{subtags, Locale}; use super::parse_locale_with_single_variant_single_keyword_unicode_extension_from_iter; pub fn parse_locale(t: &[u8]) -> Result<Locale, ParserError> { - let mut iter = get_subtag_iterator(t); + let mut iter = SubtagIterator::new(t); let id = parse_language_identifier_from_iter(&mut iter, ParserMode::Locale)?; let extensions = if iter.peek().is_some() { @@ -37,6 +37,6 @@ pub const fn parse_locale_with_single_variant_single_keyword_unicode_keyword_ext ), ParserError, > { - let iter = get_subtag_iterator(t); + let iter = SubtagIterator::new(t); parse_locale_with_single_variant_single_keyword_unicode_extension_from_iter(iter, mode) } diff --git a/vendor/icu_locid/src/parser/mod.rs b/vendor/icu_locid/src/parser/mod.rs index fef10b0ab..4b02f71c9 100644 --- a/vendor/icu_locid/src/parser/mod.rs +++ b/vendor/icu_locid/src/parser/mod.rs @@ -17,72 +17,93 @@ pub use locale::{ parse_locale, parse_locale_with_single_variant_single_keyword_unicode_keyword_extension, }; -pub const fn get_subtag_iterator(slice: &[u8]) -> SubtagIterator { - let mut current_start = 0; +#[inline] +const fn is_separator(slice: &[u8], idx: usize) -> bool { #[allow(clippy::indexing_slicing)] - while current_start < slice.len() - && (slice[current_start] == b'-' || slice[current_start] == b'_') - { - current_start += 1; - } - let mut current_end = current_start; - #[allow(clippy::indexing_slicing)] - while current_end < slice.len() && slice[current_end] != b'-' && slice[current_end] != b'_' { - current_end += 1; - } - SubtagIterator { - slice, - current_start, - current_end, + let b = slice[idx]; + b == b'-' || b == b'_' +} + +const fn get_current_subtag(slice: &[u8], idx: usize) -> (usize, usize) { + debug_assert!(idx < slice.len()); + + // This function is called only on the idx == 0 or on a separator. + let (start, mut end) = if is_separator(slice, idx) { + // If it's a separator, set the start to idx+1 and advance the idx to the next char. + (idx + 1, idx + 1) + } else { + // If it's idx=0, start is 0 and end is set to 1 + debug_assert!(idx == 0); + (0, 1) + }; + + while end < slice.len() && !is_separator(slice, end) { + // Advance until we reach end of slice or a separator. + end += 1; } + // Notice: this slice may be empty (start == end) for cases like `"en-"` or `"en--US"` + (start, end) } +// `SubtagIterator` is a helper iterator for [`LanguageIdentifier`] and [`Locale`] parsing. +// +// It is quite extraordinary due to focus on performance and Rust limitations for `const` +// functions. +// +// The iterator is eager and fallible allowing it to reject invalid slices such as `"-"`, `"-en"`, +// `"en-"` etc. +// +// The iterator provides methods available for static users - `next_manual` and `peek_manual`, +// as well as typical `Peekable` iterator APIs - `next` and `peek`. +// +// All methods return an `Option` of a `Result`. #[derive(Copy, Clone, Debug)] pub struct SubtagIterator<'a> { - slice: &'a [u8], - current_start: usize, - current_end: usize, + pub slice: &'a [u8], + done: bool, + // done + subtag is faster than Option<(usize, usize)> + // at the time of writing. + subtag: (usize, usize), } -pub type ManualSlice<'a> = (&'a [u8], usize, usize); - impl<'a> SubtagIterator<'a> { - pub const fn next_manual(mut self) -> (Self, Option<ManualSlice<'a>>) { - if self.current_start == self.current_end { - (self, None) + pub const fn new(slice: &'a [u8]) -> Self { + let subtag = if slice.is_empty() || is_separator(slice, 0) { + // This returns (0, 0) which returns Some(b"") for slices like `"-en"` or `"-"` + (0, 0) } else { - let r = (self.slice, self.current_start, self.current_end); - self.current_start = self.current_end; - #[allow(clippy::indexing_slicing)] - while self.current_start < self.slice.len() - && (self.slice[self.current_start] == b'-' - || self.slice[self.current_start] == b'_') - { - self.current_start += 1; - } - self.current_end = self.current_start; - #[allow(clippy::indexing_slicing)] - while self.current_end < self.slice.len() - && self.slice[self.current_end] != b'-' - && self.slice[self.current_end] != b'_' - { - self.current_end += 1; - } - (self, Some(r)) + get_current_subtag(slice, 0) + }; + Self { + slice, + done: false, + subtag, } } - pub const fn peek_manual(&self) -> Option<ManualSlice<'a>> { - if self.current_start == self.current_end { - None + pub const fn next_manual(mut self) -> (Self, Option<(usize, usize)>) { + if self.done { + return (self, None); + } + let result = self.subtag; + if result.1 < self.slice.len() { + self.subtag = get_current_subtag(self.slice, result.1); } else { - Some((self.slice, self.current_start, self.current_end)) + self.done = true; } + (self, Some(result)) + } + + pub const fn peek_manual(&self) -> Option<(usize, usize)> { + if self.done { + return None; + } + Some(self.subtag) } pub fn peek(&self) -> Option<&'a [u8]> { #[allow(clippy::indexing_slicing)] // peek_manual returns valid indices - self.peek_manual().map(|(t, s, e)| &t[s..e]) + self.peek_manual().map(|(s, e)| &self.slice[s..e]) } } @@ -91,8 +112,120 @@ impl<'a> Iterator for SubtagIterator<'a> { fn next(&mut self) -> Option<Self::Item> { let (s, res) = self.next_manual(); - self.clone_from(&s); + *self = s; #[allow(clippy::indexing_slicing)] // next_manual returns valid indices - res.map(|(t, s, e)| &t[s..e]) + res.map(|(s, e)| &self.slice[s..e]) + } +} + +#[cfg(test)] +mod test { + use super::*; + + fn slice_to_str(input: &[u8]) -> &str { + std::str::from_utf8(input).unwrap() + } + + #[test] + fn subtag_iterator_peek_test() { + let slice = "de_at-u-ca-foobar"; + let mut si = SubtagIterator::new(slice.as_bytes()); + + assert_eq!(si.peek().map(slice_to_str), Some("de")); + assert_eq!(si.peek().map(slice_to_str), Some("de")); + assert_eq!(si.next().map(slice_to_str), Some("de")); + + assert_eq!(si.peek().map(slice_to_str), Some("at")); + assert_eq!(si.peek().map(slice_to_str), Some("at")); + assert_eq!(si.next().map(slice_to_str), Some("at")); + } + + #[test] + fn subtag_iterator_test() { + let slice = ""; + let mut si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.next().map(slice_to_str), Some("")); + + let slice = "-"; + let mut si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.next().map(slice_to_str), Some("")); + + let slice = "-en"; + let mut si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.next().map(slice_to_str), Some("")); + assert_eq!(si.next().map(slice_to_str), Some("en")); + assert_eq!(si.next(), None); + + let slice = "en"; + let si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.map(slice_to_str).collect::<Vec<_>>(), vec!["en",]); + + let slice = "en-"; + let si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.map(slice_to_str).collect::<Vec<_>>(), vec!["en", "",]); + + let slice = "--"; + let mut si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.next().map(slice_to_str), Some("")); + assert_eq!(si.next().map(slice_to_str), Some("")); + assert_eq!(si.next().map(slice_to_str), Some("")); + assert_eq!(si.next(), None); + + let slice = "-en-"; + let mut si = SubtagIterator::new(slice.as_bytes()); + assert_eq!(si.next().map(slice_to_str), Some("")); + assert_eq!(si.next().map(slice_to_str), Some("en")); + assert_eq!(si.next().map(slice_to_str), Some("")); + assert_eq!(si.next(), None); + + let slice = "de_at-u-ca-foobar"; + let si = SubtagIterator::new(slice.as_bytes()); + assert_eq!( + si.map(slice_to_str).collect::<Vec<_>>(), + vec!["de", "at", "u", "ca", "foobar",] + ); + } + + #[test] + fn get_current_subtag_test() { + let slice = "-"; + let current = get_current_subtag(slice.as_bytes(), 0); + assert_eq!(current, (1, 1)); + + let slice = "-en"; + let current = get_current_subtag(slice.as_bytes(), 0); + assert_eq!(current, (1, 3)); + + let slice = "-en-"; + let current = get_current_subtag(slice.as_bytes(), 3); + assert_eq!(current, (4, 4)); + + let slice = "en-"; + let current = get_current_subtag(slice.as_bytes(), 0); + assert_eq!(current, (0, 2)); + + let current = get_current_subtag(slice.as_bytes(), 2); + assert_eq!(current, (3, 3)); + + let slice = "en--US"; + let current = get_current_subtag(slice.as_bytes(), 0); + assert_eq!(current, (0, 2)); + + let current = get_current_subtag(slice.as_bytes(), 2); + assert_eq!(current, (3, 3)); + + let current = get_current_subtag(slice.as_bytes(), 3); + assert_eq!(current, (4, 6)); + + let slice = "--"; + let current = get_current_subtag(slice.as_bytes(), 0); + assert_eq!(current, (1, 1)); + + let current = get_current_subtag(slice.as_bytes(), 1); + assert_eq!(current, (2, 2)); + + let slice = "-"; + let current = get_current_subtag(slice.as_bytes(), 0); + assert_eq!(current, (1, 1)); } } diff --git a/vendor/icu_locid/src/subtags/language.rs b/vendor/icu_locid/src/subtags/language.rs index a5ec8d76e..86b51b93a 100644 --- a/vendor/icu_locid/src/subtags/language.rs +++ b/vendor/icu_locid/src/subtags/language.rs @@ -55,7 +55,6 @@ impl Language { /// use icu::locid::subtags::Language; /// /// assert_eq!(Language::default(), Language::UND); - /// assert_eq!("und", Language::UND.to_string()); /// ``` pub const UND: Self = unsafe { Self::from_raw_unchecked(*b"und") }; @@ -64,15 +63,15 @@ impl Language { /// # Examples /// /// ``` - /// use icu::locid::subtags::Language; + /// use icu::locid::{subtags::Language, subtags_language as language}; /// - /// let mut lang: Language = "csb".parse().expect("Parsing failed."); + /// let mut lang = language!("csb"); /// - /// assert_eq!(lang.as_str(), "csb"); + /// assert_ne!(lang, Language::UND); /// /// lang.clear(); /// - /// assert_eq!(lang.as_str(), "und"); + /// assert_eq!(lang, Language::UND); /// ``` #[inline] pub fn clear(&mut self) { @@ -86,7 +85,7 @@ impl Language { /// ``` /// use icu::locid::subtags::Language; /// - /// let mut lang: Language = "und".parse().expect("Parsing failed."); + /// let mut lang = Language::UND; /// /// assert!(lang.is_empty()); /// diff --git a/vendor/icu_locid/src/subtags/variants.rs b/vendor/icu_locid/src/subtags/variants.rs index bbff9ebac..3bd83f149 100644 --- a/vendor/icu_locid/src/subtags/variants.rs +++ b/vendor/icu_locid/src/subtags/variants.rs @@ -16,14 +16,9 @@ use core::ops::Deref; /// # Examples /// /// ``` -/// use icu::locid::subtags::{Variant, Variants}; +/// use icu::locid::{subtags::Variants, subtags_variant as variant}; /// -/// let variant1: Variant = -/// "posix".parse().expect("Failed to parse a variant subtag."); -/// -/// let variant2: Variant = -/// "macos".parse().expect("Failed to parse a variant subtag."); -/// let mut v = vec![variant1, variant2]; +/// let mut v = vec![variant!("posix"), variant!("macos")]; /// v.sort(); /// v.dedup(); /// @@ -53,10 +48,9 @@ impl Variants { /// # Examples /// /// ``` - /// use icu::locid::subtags::{Variant, Variants}; + /// use icu::locid::{subtags::Variants, subtags_variant as variant}; /// - /// let variant: Variant = "posix".parse().expect("Parsing failed."); - /// let variants = Variants::from_variant(variant); + /// let variants = Variants::from_variant(variant!("posix")); /// ``` #[inline] pub const fn from_variant(variant: Variant) -> Self { @@ -70,11 +64,9 @@ impl Variants { /// # Examples /// /// ``` - /// use icu::locid::subtags::{Variant, Variants}; + /// use icu::locid::{subtags::Variants, subtags_variant as variant}; /// - /// let variant1: Variant = "posix".parse().expect("Parsing failed."); - /// let variant2: Variant = "macos".parse().expect("Parsing failed."); - /// let mut v = vec![variant1, variant2]; + /// let mut v = vec![variant!("posix"), variant!("macos")]; /// v.sort(); /// v.dedup(); /// @@ -95,11 +87,9 @@ impl Variants { /// # Examples /// /// ``` - /// use icu::locid::subtags::{Variant, Variants}; + /// use icu::locid::{subtags::Variants, subtags_variant as variant}; /// - /// let variant1: Variant = "posix".parse().expect("Parsing failed."); - /// let variant2: Variant = "macos".parse().expect("Parsing failed."); - /// let mut v = vec![variant1, variant2]; + /// let mut v = vec![variant!("posix"), variant!("macos")]; /// v.sort(); /// v.dedup(); /// @@ -109,7 +99,7 @@ impl Variants { /// /// variants.clear(); /// - /// assert_eq!(variants.to_string(), ""); + /// assert_eq!(variants, Variants::default()); /// ``` pub fn clear(&mut self) -> Self { core::mem::take(self) diff --git a/vendor/icu_locid/tests/fixtures/invalid-extensions.json b/vendor/icu_locid/tests/fixtures/invalid-extensions.json index a5f3a923d..3aff2636b 100644 --- a/vendor/icu_locid/tests/fixtures/invalid-extensions.json +++ b/vendor/icu_locid/tests/fixtures/invalid-extensions.json @@ -108,5 +108,45 @@ "error": "InvalidExtension", "text": "Invalid subtag" } + }, + { + "input": { + "type": "Locale", + "identifier": "de-u-ca-" + }, + "output": { + "error": "InvalidExtension", + "text": "Invalid subtag" + } + }, + { + "input": { + "type": "Locale", + "identifier": "de-u-ca-gregory-" + }, + "output": { + "error": "InvalidExtension", + "text": "Invalid subtag" + } + }, + { + "input": { + "type": "Locale", + "identifier": "de-u-ca-gregory-u-hc-hc24" + }, + "output": { + "error": "DuplicatedExtension", + "text": "Duplicated extension" + } + }, + { + "input": { + "type": "Locale", + "identifier": "de-l-foo-l-bar" + }, + "output": { + "error": "DuplicatedExtension", + "text": "Duplicated extension" + } } ] diff --git a/vendor/icu_locid/tests/fixtures/invalid.json b/vendor/icu_locid/tests/fixtures/invalid.json index d44007596..c22459e65 100644 --- a/vendor/icu_locid/tests/fixtures/invalid.json +++ b/vendor/icu_locid/tests/fixtures/invalid.json @@ -1,5 +1,54 @@ [ { + "input": "-", + "output": { + "error": "InvalidLanguage", + "text": "The given language subtag is invalid" + } + }, + { + "input": "--", + "output": { + "error": "InvalidLanguage", + "text": "The given subtag is invalid" + } + }, + { + "input": "en-", + "output": { + "error": "InvalidSubtag", + "text": "The given subtag is invalid" + } + }, + { + "input": "-en", + "output": { + "error": "InvalidLanguage", + "text": "The given subtag is invalid" + } + }, + { + "input": "en-us-", + "output": { + "error": "InvalidSubtag", + "text": "The given subtag is invalid" + } + }, + { + "input": "en--US", + "output": { + "error": "InvalidSubtag", + "text": "The given subtag is invalid" + } + }, + { + "input": "-e-", + "output": { + "error": "InvalidLanguage", + "text": "The given subtag is invalid" + } + }, + { "input": "a1a", "output": { "error": "InvalidLanguage", diff --git a/vendor/icu_locid/tests/fixtures/mod.rs b/vendor/icu_locid/tests/fixtures/mod.rs index b688632ba..f00fd6c3b 100644 --- a/vendor/icu_locid/tests/fixtures/mod.rs +++ b/vendor/icu_locid/tests/fixtures/mod.rs @@ -248,6 +248,7 @@ impl From<LocaleError> for ParserError { "InvalidLanguage" => ParserError::InvalidLanguage, "InvalidSubtag" => ParserError::InvalidSubtag, "InvalidExtension" => ParserError::InvalidExtension, + "DuplicatedExtension" => ParserError::DuplicatedExtension, _ => unreachable!("Unknown error name"), } } diff --git a/vendor/icu_locid/tests/langid.rs b/vendor/icu_locid/tests/langid.rs index 96d022a9b..60414e087 100644 --- a/vendor/icu_locid/tests/langid.rs +++ b/vendor/icu_locid/tests/langid.rs @@ -6,6 +6,7 @@ mod fixtures; mod helpers; use std::convert::TryInto; +use writeable::*; use icu_locid::{subtags, LanguageIdentifier, ParserError}; @@ -21,7 +22,7 @@ fn test_langid_fixtures(tests: Vec<fixtures::LocaleTest>) { } } let input: LanguageIdentifier = test.input.try_into().expect("Parsing failed."); - assert_eq!(input.to_string(), s); + assert_writeable_eq!(input, s); } fixtures::LocaleInfo::Error(err) => { let err: ParserError = err.into(); @@ -83,28 +84,28 @@ fn test_langid_subtag_language() { assert_eq!(lang, subtags::Language::UND); assert!(lang.is_empty()); - assert_eq!(lang.to_string(), "und"); + assert_writeable_eq!(lang, "und"); } #[test] fn test_langid_subtag_region() { let region: subtags::Region = "en".parse().expect("Failed to parse a region."); assert_eq!(region.as_str(), "EN"); - assert_eq!(region.to_string(), "EN"); + assert_writeable_eq!(region, "EN"); } #[test] fn test_langid_subtag_script() { let script: subtags::Script = "Latn".parse().expect("Failed to parse a script."); assert_eq!(script.as_str(), "Latn"); - assert_eq!(script.to_string(), "Latn"); + assert_writeable_eq!(script, "Latn"); } #[test] fn test_langid_subtag_variant() { let variant: subtags::Variant = "macos".parse().expect("Failed to parse a variant."); assert_eq!(variant.as_str(), "macos"); - assert_eq!(variant.to_string(), "macos"); + assert_writeable_eq!(variant, "macos"); } #[test] @@ -123,7 +124,7 @@ fn test_langid_normalizing_eq_str() { helpers::read_fixture(path).expect("Failed to read a fixture"); for test in tests { let parsed: LanguageIdentifier = test.input.try_into().expect("Parsing failed."); - assert!(parsed.normalizing_eq(parsed.to_string().as_str())); + assert!(parsed.normalizing_eq(&*parsed.write_to_string())); } // Check that trailing characters are not ignored @@ -148,7 +149,7 @@ fn test_langid_strict_cmp() { let a_langid = a .parse::<LanguageIdentifier>() .expect("Invalid BCP-47 in fixture"); - let a_normalized = a_langid.to_string(); + let a_normalized = a_langid.write_to_string(); let string_cmp = a_normalized.as_bytes().cmp(b.as_bytes()); let test_cmp = a_langid.strict_cmp(b.as_bytes()); assert_eq!(string_cmp, test_cmp, "{:?}/{:?}", a, b); diff --git a/vendor/icu_locid/tests/locale.rs b/vendor/icu_locid/tests/locale.rs index 37c43181e..cd3448983 100644 --- a/vendor/icu_locid/tests/locale.rs +++ b/vendor/icu_locid/tests/locale.rs @@ -6,6 +6,7 @@ mod fixtures; mod helpers; use std::convert::TryInto; +use writeable::*; use icu_locid::{LanguageIdentifier, Locale, ParserError}; @@ -16,7 +17,7 @@ fn test_langid_fixtures(tests: Vec<fixtures::LocaleTest>) { match test.output { fixtures::LocaleInfo::String(s) => { let input: Locale = test.input.try_into().expect("Parsing failed."); - assert_eq!(input.to_string(), s); + assert_writeable_eq!(input, s); } fixtures::LocaleInfo::Error(err) => { let err: ParserError = err.into(); @@ -27,7 +28,7 @@ fn test_langid_fixtures(tests: Vec<fixtures::LocaleTest>) { let input: Locale = test.input.try_into().expect("Parsing failed."); let output: Locale = ident.clone().try_into().expect("Parsing failed."); assert_eq!(input, output); - assert_eq!(input.to_string(), ident.identifier); + assert_writeable_eq!(input, ident.identifier); } fixtures::LocaleInfo::Object(o) => { let input: Locale = test.input.try_into().expect("Parsing failed."); @@ -58,7 +59,7 @@ fn test_langid_invalid() { fn test_locale_is_empty() { let locale: Locale = Locale::default(); assert!(locale.extensions.is_empty()); - assert_eq!(locale.to_string(), "und".to_string()); + assert_writeable_eq!(locale, "und"); } #[test] @@ -74,10 +75,7 @@ fn test_locale_canonicalize() { let locale: Locale = "En-latn-US-MacOS" .parse() .expect("Failed to parse a locale."); - assert_eq!( - locale.to_string(), - Locale::canonicalize("eN-latN-uS-macOS").unwrap() - ); + assert_writeable_eq!(locale, Locale::canonicalize("eN-latN-uS-macOS").unwrap()); } #[test] @@ -87,7 +85,7 @@ fn test_locale_normalizing_eq_str() { helpers::read_fixture(path).expect("Failed to read a fixture"); for test in tests { let parsed: Locale = test.input.try_into().expect("Parsing failed."); - assert!(parsed.normalizing_eq(parsed.to_string().as_str())); + assert!(parsed.normalizing_eq(&*parsed.write_to_string())); } // Check that trailing characters are not ignored @@ -113,7 +111,7 @@ fn test_locale_strict_cmp() { for a in bcp47_strings.iter() { for b in bcp47_strings.iter() { let a_langid = a.parse::<Locale>().expect("Invalid BCP-47 in fixture"); - let a_normalized = a_langid.to_string(); + let a_normalized = a_langid.write_to_string(); let string_cmp = a_normalized.as_bytes().cmp(b.as_bytes()); let test_cmp = a_langid.strict_cmp(b.as_bytes()); assert_eq!(string_cmp, test_cmp, "{:?}/{:?}", a, b); |