summaryrefslogtreecommitdiffstats
path: root/vendor/icu_provider_adapters
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /vendor/icu_provider_adapters
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/icu_provider_adapters')
-rw-r--r--vendor/icu_provider_adapters/.cargo-checksum.json2
-rw-r--r--vendor/icu_provider_adapters/Cargo.toml33
-rw-r--r--vendor/icu_provider_adapters/LICENSE79
-rw-r--r--vendor/icu_provider_adapters/README.md4
-rw-r--r--vendor/icu_provider_adapters/src/fallback/adapter.rs284
-rw-r--r--vendor/icu_provider_adapters/src/fallback/algorithms.rs439
-rw-r--r--vendor/icu_provider_adapters/src/fallback/mod.rs624
-rw-r--r--vendor/icu_provider_adapters/src/fallback/provider.rs111
-rw-r--r--vendor/icu_provider_adapters/src/filter/impls.rs4
-rw-r--r--vendor/icu_provider_adapters/src/filter/mod.rs2
-rw-r--r--vendor/icu_provider_adapters/src/fork/by_error.rs10
-rw-r--r--vendor/icu_provider_adapters/src/fork/macros.rs25
-rw-r--r--vendor/icu_provider_adapters/src/fork/mod.rs20
-rw-r--r--vendor/icu_provider_adapters/src/fork/predicates.rs7
-rw-r--r--vendor/icu_provider_adapters/tests/data/blob.postcardbin0 -> 5210 bytes
-rw-r--r--vendor/icu_provider_adapters/tests/data/config.json21
-rw-r--r--vendor/icu_provider_adapters/tests/data/langtest/de.json23
-rw-r--r--vendor/icu_provider_adapters/tests/data/langtest/ro.json23
18 files changed, 410 insertions, 1301 deletions
diff --git a/vendor/icu_provider_adapters/.cargo-checksum.json b/vendor/icu_provider_adapters/.cargo-checksum.json
index 7b2a6906a..833d0f9e7 100644
--- a/vendor/icu_provider_adapters/.cargo-checksum.json
+++ b/vendor/icu_provider_adapters/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"bc35c9045058859105d040996e5f8f204a2337b832f1a23cf6f1d10fb1eb45ee","LICENSE":"4ad7541d66a407234e2c84902124cef325c29f3e966353efdb800bedb8b8da21","README.md":"e6a08c2bc307b66c93de20c2c366da896f7fd3f5e5eb402edd2eeba79476b600","src/any_payload.rs":"165d41d018a611a7ef25dab621bbd408e6ba22dde58365817944898de138be3e","src/either.rs":"02e646af7aa6d8af1a03e448bedb2498b026d418de8340a5be52b1d366ad9b6c","src/empty.rs":"1503b2f73b2a727a9e502ab7081da3261df470bc86b762ab5748c31fad8cfbc6","src/fallback/adapter.rs":"55188c9acb6ddc852b9218b14c97304e0378f9e40eedb0f0af41b5036a78e54f","src/fallback/algorithms.rs":"9409ad6f6f617d4433b9f6b303d131782877a0a10470533e3864b97355b9a3f1","src/fallback/mod.rs":"9a1ba8dcba21dbcb5acc4a019d640fffcfd2efd043bfa42a5690a9de593479d1","src/fallback/provider.rs":"ef8a835e3ed2b7871b6f6e78ae2e73575b26adc9e8e0b5a7170c8513e7fe3269","src/filter/impls.rs":"588918fdcadda3572844352bf22419910ee6430f3e5a6e7c5e012120ad2eb932","src/filter/mod.rs":"33a622b9684c5e445b2af8aec9cd3ba5dfe3b51d917dd2776b267657e6a5b72d","src/fork/by_error.rs":"450a24bfaa17e32899e4ba4286623b2b3b36af81fb5abd9b1e28a2af18c3b9dc","src/fork/macros.rs":"5aebb0134923fa9fa0fe7c16d2d85a1a29cf4ea49505187db56bf0bc8e984ad0","src/fork/mod.rs":"7378895128bf1ccc9de7f5675668ef922d3df7b84b04f68af4d5b49efe60341e","src/fork/predicates.rs":"314bf33144c6827cd3df05877d7c20fb64c9b18f6230e229340b8f04f4ccf4d3","src/helpers.rs":"0e5c8424c9e51956cd065d4ecf4f478bbc3978888b4bbb012ad3f5d6a7062fb1","src/lib.rs":"243ec29c6e5fbe59004f5774f1b252166b06a264e218a7209fe6ed83c25dd03a","tests/data/langtest/de/core/helloworld@1/de.json":"5a45b1d80567de8c4ff754f7dbe20c22477c1e00a9400b38397eb034f295b8f8","tests/data/langtest/de/manifest.json":"fa2f848cff051fd12a909389fbbc44b93ae1feb92cce466cc4381f9548443ea9","tests/data/langtest/ro/core/helloworld@1/ro.json":"b6b68292746dd6bb2d92d9c08e2753db556ec9c954a3b593b0b8999df550f298","tests/data/langtest/ro/manifest.json":"fa2f848cff051fd12a909389fbbc44b93ae1feb92cce466cc4381f9548443ea9"},"package":"f4ae1e2bd0c41728b77e7c46e9afdec5e2127d1eedacc684724667d50c126bd3"} \ No newline at end of file
+{"files":{"Cargo.toml":"cc4c433c73faa394a0bd721e086c1dfcd238e4efd6540886632e4be4b62183df","LICENSE":"853f87c96f3d249f200fec6db1114427bc8bdf4afddc93c576956d78152ce978","README.md":"d91500cb944c05c04ed9e6920d139199a9d1892346de50dccbdce5cbef3b9174","src/any_payload.rs":"165d41d018a611a7ef25dab621bbd408e6ba22dde58365817944898de138be3e","src/either.rs":"02e646af7aa6d8af1a03e448bedb2498b026d418de8340a5be52b1d366ad9b6c","src/empty.rs":"1503b2f73b2a727a9e502ab7081da3261df470bc86b762ab5748c31fad8cfbc6","src/fallback/mod.rs":"7f0cfc915cb95d1681befc52ef51ecaec0c900043a15d3feba3e5a8cc23c39ff","src/filter/impls.rs":"17b6ba2c7c72b72a72fbc57f31eec0cbe52d631a87012f6604fb1bf2e9f9137d","src/filter/mod.rs":"896de77291b093886a210dcbb30498aef2c9afe4ce984bd2ac517323e96917b4","src/fork/by_error.rs":"d7fee843306ab8b6e5de2abea8efb4409d01e2faf15fcb2ab4f6ba3cb0f47a09","src/fork/macros.rs":"9e8c071d7c21b93b4d07672542ec994d2fde2c19f14dd30f5c969215c73ebda7","src/fork/mod.rs":"64502e4d8a667e1ec5aa8339e07c1f2e5b0021e6ee4ca06722f6a1793f0e2b0d","src/fork/predicates.rs":"1191f9ff1ae2196255effb50e245a3f80c2a4429ea3e46499f0284835a51c1c9","src/helpers.rs":"0e5c8424c9e51956cd065d4ecf4f478bbc3978888b4bbb012ad3f5d6a7062fb1","src/lib.rs":"243ec29c6e5fbe59004f5774f1b252166b06a264e218a7209fe6ed83c25dd03a","tests/data/blob.postcard":"ae4478ddd635aa0f816d2abae9057dc9df0d9963e6b78b1b8e8722b318a513c5","tests/data/config.json":"0ec2a3ec6338767cee5e9bd1c27dceafcc10c28b5e0380059b7faf2f0cf707b7","tests/data/langtest/de.json":"6016405e1d9c63c2df940953fc3ae064b1fc4c0e3676ed78fafe4ec84596dfa3","tests/data/langtest/de/core/helloworld@1/de.json":"5a45b1d80567de8c4ff754f7dbe20c22477c1e00a9400b38397eb034f295b8f8","tests/data/langtest/de/manifest.json":"fa2f848cff051fd12a909389fbbc44b93ae1feb92cce466cc4381f9548443ea9","tests/data/langtest/ro.json":"c6ba5912f3ef51357c2d92596cd13b78080aee257132395d900ba4c76450c9ca","tests/data/langtest/ro/core/helloworld@1/ro.json":"b6b68292746dd6bb2d92d9c08e2753db556ec9c954a3b593b0b8999df550f298","tests/data/langtest/ro/manifest.json":"fa2f848cff051fd12a909389fbbc44b93ae1feb92cce466cc4381f9548443ea9"},"package":"36b380ef2d3d93b015cd0563d7e0d005cc07f82a5503716dbc191798d0079e1d"} \ No newline at end of file
diff --git a/vendor/icu_provider_adapters/Cargo.toml b/vendor/icu_provider_adapters/Cargo.toml
index 291a17ffc..72f4592a7 100644
--- a/vendor/icu_provider_adapters/Cargo.toml
+++ b/vendor/icu_provider_adapters/Cargo.toml
@@ -11,10 +11,12 @@
[package]
edition = "2021"
+rust-version = "1.66"
name = "icu_provider_adapters"
-version = "1.2.0"
+version = "1.3.2"
authors = ["The ICU4X Project Developers"]
include = [
+ "data/**/*",
"src/**/*",
"examples/**/*",
"benches/**/*",
@@ -24,23 +26,31 @@ include = [
"README.md",
]
description = "Adapters for composing and manipulating data providers."
+homepage = "https://icu4x.unicode.org"
readme = "README.md"
categories = ["internationalization"]
-license = "Unicode-DFS-2016"
+license-file = "LICENSE"
repository = "https://github.com/unicode-org/icu4x"
[dependencies.databake]
-version = "0.1.3"
+version = "0.1.6"
features = ["derive"]
optional = true
+default-features = false
[dependencies.icu_locid]
-version = "1.2.0"
+version = "~1.3.2"
features = ["zerovec"]
+default-features = false
+
+[dependencies.icu_locid_transform]
+version = "~1.3.2"
+default-features = false
[dependencies.icu_provider]
-version = "1.2.0"
+version = "~1.3.2"
features = ["macros"]
+default-features = false
[dependencies.serde]
version = "1.0"
@@ -52,15 +62,14 @@ optional = true
default-features = false
[dependencies.tinystr]
-version = "0.7.1"
+version = "0.7.3"
features = ["zerovec"]
-
-[dependencies.yoke]
-version = "0.7.1"
+default-features = false
[dependencies.zerovec]
-version = "0.9.4"
+version = "0.10.0"
features = ["yoke"]
+default-features = false
[dev-dependencies]
@@ -68,15 +77,13 @@ features = ["yoke"]
datagen = [
"std",
"serde",
- "dep:databake",
"icu_provider/datagen",
- "icu_locid/databake",
- "zerovec/databake",
]
serde = [
"dep:serde",
"zerovec/serde",
"icu_locid/serde",
+ "icu_locid_transform/serde",
"icu_provider/serde",
]
std = [
diff --git a/vendor/icu_provider_adapters/LICENSE b/vendor/icu_provider_adapters/LICENSE
index 9858d01ab..9845aa5f4 100644
--- a/vendor/icu_provider_adapters/LICENSE
+++ b/vendor/icu_provider_adapters/LICENSE
@@ -1,49 +1,42 @@
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-See Terms of Use <https://www.unicode.org/copyright.html>
-for definitions of Unicode Inc.’s Data Files and Software.
-
-NOTICE TO USER: Carefully read the following legal agreement.
-BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S
-DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"),
-YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
-TERMS AND CONDITIONS OF THIS AGREEMENT.
-IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE
-THE DATA FILES OR SOFTWARE.
+UNICODE LICENSE V3
COPYRIGHT AND PERMISSION NOTICE
-Copyright © 1991-2022 Unicode, Inc. All rights reserved.
-Distributed under the Terms of Use in https://www.unicode.org/copyright.html.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Unicode data files and any associated documentation
-(the "Data Files") or Unicode software and any associated documentation
-(the "Software") to deal in the Data Files or Software
-without restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, and/or sell copies of
-the Data Files or Software, and to permit persons to whom the Data Files
-or Software are furnished to do so, provided that either
-(a) this copyright and permission notice appear with all copies
-of the Data Files or Software, or
-(b) this copyright and permission notice appear in associated
-Documentation.
-
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
-NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
-DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
-DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THE DATA FILES OR SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder
-shall not be used in advertising or otherwise to promote the sale,
-use or other dealings in these Data Files or Software without prior
-written authorization of the copyright holder.
+Copyright © 2020-2023 Unicode, Inc.
+
+NOTICE TO USER: Carefully read the following legal agreement. BY
+DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
+SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
+TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
+DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of data files and any associated documentation (the "Data Files") or
+software and any associated documentation (the "Software") to deal in the
+Data Files or Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, and/or sell
+copies of the Data Files or Software, and to permit persons to whom the
+Data Files or Software are furnished to do so, provided that either (a)
+this copyright and permission notice appear with all copies of the Data
+Files or Software, or (b) this copyright and permission notice appear in
+associated Documentation.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
+THIRD PARTY RIGHTS.
+
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE
+BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
+OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA
+FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder shall
+not be used in advertising or otherwise to promote the sale, use or other
+dealings in these Data Files or Software without prior written
+authorization of the copyright holder.
diff --git a/vendor/icu_provider_adapters/README.md b/vendor/icu_provider_adapters/README.md
index 28a29e6bc..fcbdce2c3 100644
--- a/vendor/icu_provider_adapters/README.md
+++ b/vendor/icu_provider_adapters/README.md
@@ -1,5 +1,7 @@
# icu_provider_adapters [![crates.io](https://img.shields.io/crates/v/icu_provider_adapters)](https://crates.io/crates/icu_provider_adapters)
+<!-- cargo-rdme start -->
+
Adapters for composing and manipulating data providers.
- Use the [`fork`] module to marshall data requests between multiple possible providers.
@@ -7,6 +9,8 @@ Adapters for composing and manipulating data providers.
- Use the [`filter`] module to programmatically reject certain data requests.
- Use the [`fallback`] module to automatically resolve arbitrary locales for data loading.
+<!-- cargo-rdme end -->
+
## More Information
For more information on development, authorship, contributing etc. please visit [`ICU4X home page`](https://github.com/unicode-org/icu4x).
diff --git a/vendor/icu_provider_adapters/src/fallback/adapter.rs b/vendor/icu_provider_adapters/src/fallback/adapter.rs
deleted file mode 100644
index 8d9d79f2d..000000000
--- a/vendor/icu_provider_adapters/src/fallback/adapter.rs
+++ /dev/null
@@ -1,284 +0,0 @@
-// This file is part of ICU4X. For terms of use, please see the file
-// called LICENSE at the top level of the ICU4X source tree
-// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
-
-use super::*;
-use crate::helpers::result_is_err_missing_locale;
-
-/// A data provider wrapper that performs locale fallback. This enables arbitrary locales to be
-/// handled at runtime.
-///
-/// # Examples
-///
-/// ```
-/// use icu_locid::locale;
-/// use icu_provider::prelude::*;
-/// use icu_provider::hello_world::*;
-/// use icu_provider_adapters::fallback::LocaleFallbackProvider;
-///
-/// let provider = icu_testdata::unstable_no_fallback();
-///
-/// let req = DataRequest {
-/// locale: &locale!("ja-JP").into(),
-/// metadata: Default::default(),
-/// };
-///
-/// // The provider does not have data for "ja-JP":
-/// DataProvider::<HelloWorldV1Marker>::load(&provider, req).expect_err("No fallback");
-///
-/// // But if we wrap the provider in a fallback provider...
-/// let provider = LocaleFallbackProvider::try_new_unstable(provider)
-/// .expect("Fallback data present");
-///
-/// // ...then we can load "ja-JP" based on "ja" data
-/// let response =
-/// DataProvider::<HelloWorldV1Marker>::load(&provider, req).expect("successful with vertical fallback");
-///
-/// assert_eq!(
-/// response.metadata.locale.unwrap(),
-/// locale!("ja").into(),
-/// );
-/// assert_eq!(
-/// response.payload.unwrap().get().message,
-/// "こんにちは世界",
-/// );
-/// ```
-#[derive(Clone, Debug)]
-pub struct LocaleFallbackProvider<P> {
- inner: P,
- fallbacker: LocaleFallbacker,
-}
-
-impl<P> LocaleFallbackProvider<P>
-where
- P: DataProvider<LocaleFallbackLikelySubtagsV1Marker>
- + DataProvider<LocaleFallbackParentsV1Marker>
- + DataProvider<CollationFallbackSupplementV1Marker>,
-{
- /// Create a [`LocaleFallbackProvider`] by wrapping another data provider and then loading
- /// fallback data from it.
- ///
- /// If the data provider being wrapped does not contain fallback data, use
- /// [`LocaleFallbackProvider::new_with_fallbacker`].
- pub fn try_new_unstable(provider: P) -> Result<Self, DataError> {
- let fallbacker = LocaleFallbacker::try_new_unstable(&provider)?;
- Ok(Self {
- inner: provider,
- fallbacker,
- })
- }
-}
-
-impl<P> LocaleFallbackProvider<P>
-where
- P: AnyProvider,
-{
- /// Create a [`LocaleFallbackProvider`] by wrapping another data provider and then loading
- /// fallback data from it.
- ///
- /// If the data provider being wrapped does not contain fallback data, use
- /// [`LocaleFallbackProvider::new_with_fallbacker`].
- pub fn try_new_with_any_provider(provider: P) -> Result<Self, DataError> {
- let fallbacker = LocaleFallbacker::try_new_with_any_provider(&provider)?;
- Ok(Self {
- inner: provider,
- fallbacker,
- })
- }
-}
-
-#[cfg(feature = "serde")]
-impl<P> LocaleFallbackProvider<P>
-where
- P: BufferProvider,
-{
- /// Create a [`LocaleFallbackProvider`] by wrapping another data provider and then loading
- /// fallback data from it.
- ///
- /// If the data provider being wrapped does not contain fallback data, use
- /// [`LocaleFallbackProvider::new_with_fallbacker`].
- pub fn try_new_with_buffer_provider(provider: P) -> Result<Self, DataError> {
- let fallbacker = LocaleFallbacker::try_new_with_buffer_provider(&provider)?;
- Ok(Self {
- inner: provider,
- fallbacker,
- })
- }
-}
-
-impl<P> LocaleFallbackProvider<P> {
- /// Wrap a provider with an arbitrary fallback engine.
- ///
- /// This relaxes the requirement that the wrapped provider contains its own fallback data.
- ///
- /// # Examples
- ///
- /// ```
- /// use icu_locid::locale;
- /// use icu_provider::hello_world::*;
- /// use icu_provider::prelude::*;
- /// use icu_provider_adapters::fallback::{
- /// LocaleFallbackProvider, LocaleFallbacker,
- /// };
- ///
- /// let provider = HelloWorldProvider;
- ///
- /// let req = DataRequest {
- /// locale: &locale!("de-CH").into(),
- /// metadata: Default::default(),
- /// };
- ///
- /// // There is no "de-CH" data in the `HelloWorldProvider`
- /// DataProvider::<HelloWorldV1Marker>::load(&provider, req)
- /// .expect_err("No data for de-CH");
- ///
- /// // `HelloWorldProvider` does not contain fallback data,
- /// // but we can fetch it from `icu_testdata`, and then
- /// // use it to create the fallbacking data provider.
- /// let fallbacker =
- /// LocaleFallbacker::try_new_unstable(&icu_testdata::unstable())
- /// .expect("Fallback data present");
- /// let provider =
- /// LocaleFallbackProvider::new_with_fallbacker(provider, fallbacker);
- ///
- /// // Now we can load the "de-CH" data via fallback to "de".
- /// let german_hello_world: DataPayload<HelloWorldV1Marker> = provider
- /// .load(req)
- /// .expect("Loading should succeed")
- /// .take_payload()
- /// .expect("Data should be present");
- ///
- /// assert_eq!("Hallo Welt", german_hello_world.get().message);
- /// ```
- pub fn new_with_fallbacker(provider: P, fallbacker: LocaleFallbacker) -> Self {
- Self {
- inner: provider,
- fallbacker,
- }
- }
-
- /// Returns a reference to the inner provider, bypassing fallback.
- pub fn inner(&self) -> &P {
- &self.inner
- }
-
- /// Returns a mutable reference to the inner provider.
- pub fn inner_mut(&mut self) -> &mut P {
- &mut self.inner
- }
-
- /// Returns ownership of the inner provider to the caller.
- pub fn into_inner(self) -> P {
- self.inner
- }
-
- /// Run the fallback algorithm with the data request using the inner data provider.
- /// Internal function; external clients should use one of the trait impls below.
- ///
- /// Function arguments:
- ///
- /// - F1 should perform a data load for a single DataRequest and return the result of it
- /// - F2 should map from the provider-specific response type to DataResponseMetadata
- fn run_fallback<F1, F2, R>(
- &self,
- key: DataKey,
- mut base_req: DataRequest,
- mut f1: F1,
- mut f2: F2,
- ) -> Result<R, DataError>
- where
- F1: FnMut(DataRequest) -> Result<R, DataError>,
- F2: FnMut(&mut R) -> &mut DataResponseMetadata,
- {
- let key_fallbacker = self.fallbacker.for_key(key);
- let mut fallback_iterator = key_fallbacker.fallback_for(base_req.locale.clone());
- let base_silent = core::mem::replace(&mut base_req.metadata.silent, true);
- loop {
- let result = f1(DataRequest {
- locale: fallback_iterator.get(),
- metadata: base_req.metadata,
- });
- if !result_is_err_missing_locale(&result) {
- return result
- .map(|mut res| {
- f2(&mut res).locale = Some(fallback_iterator.take());
- res
- })
- // Log the original request rather than the fallback request
- .map_err(|e| {
- base_req.metadata.silent = base_silent;
- e.with_req(key, base_req)
- });
- }
- // If we just checked und, break out of the loop.
- if fallback_iterator.get().is_empty() {
- break;
- }
- fallback_iterator.step();
- }
- base_req.metadata.silent = base_silent;
- Err(DataErrorKind::MissingLocale.with_req(key, base_req))
- }
-}
-
-impl<P> AnyProvider for LocaleFallbackProvider<P>
-where
- P: AnyProvider,
-{
- fn load_any(&self, key: DataKey, base_req: DataRequest) -> Result<AnyResponse, DataError> {
- self.run_fallback(
- key,
- base_req,
- |req| self.inner.load_any(key, req),
- |res| &mut res.metadata,
- )
- }
-}
-
-impl<P> BufferProvider for LocaleFallbackProvider<P>
-where
- P: BufferProvider,
-{
- fn load_buffer(
- &self,
- key: DataKey,
- base_req: DataRequest,
- ) -> Result<DataResponse<BufferMarker>, DataError> {
- self.run_fallback(
- key,
- base_req,
- |req| self.inner.load_buffer(key, req),
- |res| &mut res.metadata,
- )
- }
-}
-
-impl<P, M> DynamicDataProvider<M> for LocaleFallbackProvider<P>
-where
- P: DynamicDataProvider<M>,
- M: DataMarker,
-{
- fn load_data(&self, key: DataKey, base_req: DataRequest) -> Result<DataResponse<M>, DataError> {
- self.run_fallback(
- key,
- base_req,
- |req| self.inner.load_data(key, req),
- |res| &mut res.metadata,
- )
- }
-}
-
-impl<P, M> DataProvider<M> for LocaleFallbackProvider<P>
-where
- P: DataProvider<M>,
- M: KeyedDataMarker,
-{
- fn load(&self, base_req: DataRequest) -> Result<DataResponse<M>, DataError> {
- self.run_fallback(
- M::KEY,
- base_req,
- |req| self.inner.load(req),
- |res| &mut res.metadata,
- )
- }
-}
diff --git a/vendor/icu_provider_adapters/src/fallback/algorithms.rs b/vendor/icu_provider_adapters/src/fallback/algorithms.rs
deleted file mode 100644
index 0edc59304..000000000
--- a/vendor/icu_provider_adapters/src/fallback/algorithms.rs
+++ /dev/null
@@ -1,439 +0,0 @@
-// This file is part of ICU4X. For terms of use, please see the file
-// called LICENSE at the top level of the ICU4X source tree
-// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
-
-use icu_locid::extensions::unicode::Key;
-use icu_locid::extensions_unicode_key as key;
-use icu_locid::subtags::Language;
-use icu_locid::LanguageIdentifier;
-use icu_provider::FallbackPriority;
-
-use super::*;
-
-const SUBDIVISION_KEY: Key = key!("sd");
-
-impl<'a> LocaleFallbackerWithConfig<'a> {
- pub(crate) fn normalize(&self, locale: &mut DataLocale) {
- let language = locale.language();
- // 1. Populate the region (required for region fallback only)
- if self.config.priority == FallbackPriority::Region && locale.region().is_none() {
- // 1a. First look for region based on language+script
- if let Some(script) = locale.script() {
- locale.set_region(
- self.likely_subtags
- .ls2r
- .get_2d(&language.into(), &script.into())
- .copied(),
- );
- }
- // 1b. If that fails, try language only
- if locale.region().is_none() {
- locale.set_region(self.likely_subtags.l2r.get(&language.into()).copied());
- }
- }
- // 2. Remove the script if it is implied by the other subtags
- if let Some(script) = locale.script() {
- let default_script = self
- .likely_subtags
- .l2s
- .get_copied(&language.into())
- .unwrap_or(DEFAULT_SCRIPT);
- if let Some(region) = locale.region() {
- if script
- == self
- .likely_subtags
- .lr2s
- .get_copied_2d(&language.into(), &region.into())
- .unwrap_or(default_script)
- {
- locale.set_script(None);
- }
- } else if script == default_script {
- locale.set_script(None);
- }
- }
- // 3. Remove irrelevant extension subtags
- locale.retain_unicode_ext(|key| {
- match *key {
- // Always retain -u-sd
- SUBDIVISION_KEY => true,
- // Retain the query-specific keyword
- _ if Some(*key) == self.config.extension_key => true,
- // Drop all others
- _ => false,
- }
- });
- // 4. If there is an invalid "sd" subtag, drop it
- // For now, ignore it, and let fallback do it for us
- }
-}
-
-impl<'a, 'b> LocaleFallbackIteratorInner<'a, 'b> {
- pub fn step(&mut self, locale: &mut DataLocale) {
- match self.config.priority {
- FallbackPriority::Language => self.step_language(locale),
- FallbackPriority::Region => self.step_region(locale),
- // TODO(#1964): Change the collation fallback rules to be different
- // from the language fallback fules.
- FallbackPriority::Collation => self.step_language(locale),
- // This case should not normally happen, but `FallbackPriority` is non_exhaustive.
- // Make it go directly to `und`.
- _ => {
- debug_assert!(
- false,
- "Unknown FallbackPriority: {:?}",
- self.config.priority
- );
- *locale = Default::default()
- }
- }
- }
-
- fn step_language(&mut self, locale: &mut DataLocale) {
- // 1. Remove the extension fallback keyword
- if let Some(extension_key) = self.config.extension_key {
- if let Some(value) = locale.remove_unicode_ext(&extension_key) {
- self.backup_extension = Some(value);
- return;
- }
- }
- // 2. Remove the subdivision keyword
- if let Some(value) = locale.remove_unicode_ext(&SUBDIVISION_KEY) {
- self.backup_subdivision = Some(value);
- return;
- }
- // 3. Assert that the locale is a language identifier
- debug_assert!(!locale.has_unicode_ext());
- // 4. Remove variants
- if locale.has_variants() {
- self.backup_variants = Some(locale.clear_variants());
- return;
- }
- // 5. Check for parent override
- if let Some(parent) = self.get_explicit_parent(locale) {
- locale.set_langid(parent);
- self.restore_extensions_variants(locale);
- return;
- }
- // 6. Add the script subtag if necessary
- if locale.script().is_none() {
- if let Some(region) = locale.region() {
- let language = locale.language();
- if let Some(script) = self
- .likely_subtags
- .lr2s
- .get_copied_2d(&language.into(), &region.into())
- {
- locale.set_script(Some(script));
- self.restore_extensions_variants(locale);
- return;
- }
- }
- }
- // 7. Remove region
- if locale.region().is_some() {
- locale.set_region(None);
- return;
- }
- // 8. Remove language+script
- debug_assert!(!locale.language().is_empty()); // don't call .step() on und
- locale.set_script(None);
- locale.set_language(Language::UND);
- }
-
- fn step_region(&mut self, locale: &mut DataLocale) {
- // 1. Remove the extension fallback keyword
- if let Some(extension_key) = self.config.extension_key {
- if let Some(value) = locale.remove_unicode_ext(&extension_key) {
- self.backup_extension = Some(value);
- return;
- }
- }
- // 2. Remove the subdivision keyword
- if let Some(value) = locale.remove_unicode_ext(&SUBDIVISION_KEY) {
- self.backup_subdivision = Some(value);
- return;
- }
- // 3. Assert that the locale is a language identifier
- debug_assert!(!locale.has_unicode_ext());
- // 4. Remove variants
- if locale.has_variants() {
- self.backup_variants = Some(locale.clear_variants());
- return;
- }
- // 5. Remove language+script
- if !locale.language().is_empty() || locale.script().is_some() {
- locale.set_script(None);
- locale.set_language(Language::UND);
- self.restore_extensions_variants(locale);
- return;
- }
- // 6. Remove region
- debug_assert!(locale.region().is_some()); // don't call .step() on und
- locale.set_region(None);
- }
-
- fn restore_extensions_variants(&mut self, locale: &mut DataLocale) {
- if let Some(value) = self.backup_extension.take() {
- #[allow(clippy::unwrap_used)] // not reachable unless extension_key is present
- locale.set_unicode_ext(self.config.extension_key.unwrap(), value);
- }
- if let Some(value) = self.backup_subdivision.take() {
- locale.set_unicode_ext(SUBDIVISION_KEY, value);
- }
- if let Some(variants) = self.backup_variants.take() {
- locale.set_variants(variants);
- }
- }
-
- fn get_explicit_parent(&self, locale: &DataLocale) -> Option<LanguageIdentifier> {
- self.supplement
- .and_then(|supplement| {
- supplement
- .parents
- .get_copied_by(|uvstr| locale.strict_cmp(uvstr).reverse())
- })
- .or_else(|| {
- self.parents
- .parents
- .get_copied_by(|uvstr| locale.strict_cmp(uvstr).reverse())
- })
- .map(LanguageIdentifier::from)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use icu_locid::Locale;
- use std::str::FromStr;
- use writeable::Writeable;
-
- struct TestCase {
- input: &'static str,
- requires_data: bool,
- extension_key: Option<Key>,
- fallback_supplement: Option<FallbackSupplement>,
- // Note: The first entry in the chain is the normalized locale
- expected_language_chain: &'static [&'static str],
- expected_region_chain: &'static [&'static str],
- }
-
- // TODO: Consider loading these from a JSON file
- const TEST_CASES: &[TestCase] = &[
- TestCase {
- input: "en-u-hc-h12-sd-usca",
- requires_data: false,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["en-u-sd-usca", "en"],
- expected_region_chain: &["en-u-sd-usca", "en", "und-u-sd-usca"],
- },
- TestCase {
- input: "en-US-u-hc-h12-sd-usca",
- requires_data: false,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["en-US-u-sd-usca", "en-US", "en"],
- expected_region_chain: &["en-US-u-sd-usca", "en-US", "und-US-u-sd-usca", "und-US"],
- },
- TestCase {
- input: "en-US-fonipa-u-hc-h12-sd-usca",
- requires_data: false,
- extension_key: Some(key!("hc")),
- fallback_supplement: None,
- expected_language_chain: &[
- "en-US-fonipa-u-hc-h12-sd-usca",
- "en-US-fonipa-u-sd-usca",
- "en-US-fonipa",
- "en-US",
- "en",
- ],
- expected_region_chain: &[
- "en-US-fonipa-u-hc-h12-sd-usca",
- "en-US-fonipa-u-sd-usca",
- "en-US-fonipa",
- "en-US",
- "und-US-fonipa-u-hc-h12-sd-usca",
- "und-US-fonipa-u-sd-usca",
- "und-US-fonipa",
- "und-US",
- ],
- },
- TestCase {
- input: "en-u-hc-h12-sd-usca",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["en-u-sd-usca", "en"],
- expected_region_chain: &["en-US-u-sd-usca", "en-US", "und-US-u-sd-usca", "und-US"],
- },
- TestCase {
- input: "en-Latn-u-sd-usca",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["en-u-sd-usca", "en"],
- expected_region_chain: &["en-US-u-sd-usca", "en-US", "und-US-u-sd-usca", "und-US"],
- },
- TestCase {
- input: "en-Latn-US-u-sd-usca",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["en-US-u-sd-usca", "en-US", "en"],
- expected_region_chain: &["en-US-u-sd-usca", "en-US", "und-US-u-sd-usca", "und-US"],
- },
- TestCase {
- // NOTE: -u-rg is not yet supported; when it is, this test should be updated
- input: "en-u-rg-gbxxxx",
- requires_data: false,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["en"],
- expected_region_chain: &["en"],
- },
- TestCase {
- input: "sr-ME",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["sr-ME", "sr-Latn-ME", "sr-Latn"],
- expected_region_chain: &["sr-ME", "und-ME"],
- },
- TestCase {
- input: "sr-ME-fonipa",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &[
- "sr-ME-fonipa",
- "sr-ME",
- "sr-Latn-ME-fonipa",
- "sr-Latn-ME",
- "sr-Latn",
- ],
- expected_region_chain: &["sr-ME-fonipa", "sr-ME", "und-ME-fonipa", "und-ME"],
- },
- TestCase {
- input: "de-Latn-LI",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["de-LI", "de"],
- expected_region_chain: &["de-LI", "und-LI"],
- },
- TestCase {
- input: "ca-ES-valencia",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["ca-ES-valencia", "ca-ES", "ca"],
- expected_region_chain: &["ca-ES-valencia", "ca-ES", "und-ES-valencia", "und-ES"],
- },
- TestCase {
- input: "es-AR",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["es-AR", "es-419", "es"],
- expected_region_chain: &["es-AR", "und-AR"],
- },
- TestCase {
- input: "hi-IN",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["hi-IN", "hi"],
- expected_region_chain: &["hi-IN", "und-IN"],
- },
- TestCase {
- input: "hi-Latn-IN",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["hi-Latn-IN", "hi-Latn", "en-IN", "en-001", "en"],
- expected_region_chain: &["hi-Latn-IN", "und-IN"],
- },
- TestCase {
- input: "zh-CN",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- // Note: "zh-Hans" is not reachable because it is the default script for "zh".
- // The fallback algorithm does not visit the language-script bundle when the
- // script is the default for the language
- expected_language_chain: &["zh-CN", "zh"],
- expected_region_chain: &["zh-CN", "und-CN"],
- },
- TestCase {
- input: "zh-TW",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["zh-TW", "zh-Hant-TW", "zh-Hant"],
- expected_region_chain: &["zh-TW", "und-TW"],
- },
- TestCase {
- input: "yue-HK",
- requires_data: true,
- extension_key: None,
- fallback_supplement: None,
- expected_language_chain: &["yue-HK", "yue"],
- expected_region_chain: &["yue-HK", "und-HK"],
- },
- TestCase {
- input: "yue-HK",
- requires_data: true,
- extension_key: None,
- fallback_supplement: Some(FallbackSupplement::Collation),
- // TODO(#1964): add "zh" as a target.
- expected_language_chain: &["yue-HK", "yue", "zh-Hant"],
- expected_region_chain: &["yue-HK", "und-HK"],
- },
- ];
-
- #[test]
- #[cfg(feature = "serde")]
- fn test_fallback() {
- let fallbacker_no_data = LocaleFallbacker::new_without_data();
- let fallbacker_with_data =
- LocaleFallbacker::try_new_with_buffer_provider(&icu_testdata::buffer()).unwrap();
- for cas in TEST_CASES {
- for (priority, expected_chain) in [
- (FallbackPriority::Language, cas.expected_language_chain),
- (FallbackPriority::Region, cas.expected_region_chain),
- ] {
- let config = LocaleFallbackConfig {
- priority,
- extension_key: cas.extension_key,
- fallback_supplement: cas.fallback_supplement,
- };
- let key_fallbacker = if cas.requires_data {
- fallbacker_with_data.for_config(config)
- } else {
- fallbacker_no_data.for_config(config)
- };
- let locale = DataLocale::from(Locale::from_str(cas.input).unwrap());
- let mut it = key_fallbacker.fallback_for(locale);
- for &expected in expected_chain {
- assert_eq!(
- expected,
- &*it.get().write_to_string(),
- "{:?} ({:?})",
- cas.input,
- priority
- );
- it.step();
- }
- assert_eq!(
- "und",
- &*it.get().write_to_string(),
- "{:?} ({:?})",
- cas.input,
- priority
- );
- }
- }
- }
-}
diff --git a/vendor/icu_provider_adapters/src/fallback/mod.rs b/vendor/icu_provider_adapters/src/fallback/mod.rs
index a28620b25..c0a05d14e 100644
--- a/vendor/icu_provider_adapters/src/fallback/mod.rs
+++ b/vendor/icu_provider_adapters/src/fallback/mod.rs
@@ -2,421 +2,297 @@
// called LICENSE at the top level of the ICU4X source tree
// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
-//! Tools for locale fallback, enabling arbitrary input locales to be mapped into the nearest
-//! locale with data.
-//!
-//! The algorithm implemented in this module is called [Flexible Vertical Fallback](
-//! https://docs.google.com/document/d/1Mp7EUyl-sFh_HZYgyeVwj88vJGpCBIWxzlCwGgLCDwM/edit).
-//! Watch [#2243](https://github.com/unicode-org/icu4x/issues/2243) to track improvements to
-//! this algorithm and steps to enshrine the algorithm in CLDR.
-//!
-//! # Examples
-//!
-//! Run the locale fallback algorithm:
-//!
-//! ```
-//! use icu_locid::locale;
-//! use icu_provider_adapters::fallback::LocaleFallbacker;
-//! use icu_provider::prelude::*;
-//!
-//! // Set up a LocaleFallbacker with data.
-//! let fallbacker = LocaleFallbacker::try_new_unstable(&icu_testdata::unstable()).expect("data");
-//!
-//! // Create a LocaleFallbackerWithConfig with a configuration for a specific key.
-//! // By default, uses language priority with no additional extension keywords.
-//! let key_fallbacker = fallbacker.for_config(Default::default());
-//!
-//! // Set up the fallback iterator.
-//! let mut fallback_iterator = key_fallbacker.fallback_for(DataLocale::from(locale!("hi-Latn-IN")));
-//!
-//! // Run the algorithm and check the results.
-//! assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("hi-Latn-IN")));
-//! fallback_iterator.step();
-//! assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("hi-Latn")));
-//! fallback_iterator.step();
-//! assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("en-IN")));
-//! fallback_iterator.step();
-//! assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("en-001")));
-//! fallback_iterator.step();
-//! assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("en")));
-//! fallback_iterator.step();
-//! assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("und")));
-//! ```
+//! A data provider wrapper that performs locale fallback.
-use icu_locid::extensions::unicode::{Key, Value};
-use icu_locid::subtags::Variants;
+use crate::helpers::result_is_err_missing_locale;
+use icu_locid_transform::provider::*;
use icu_provider::prelude::*;
-use icu_provider::FallbackPriority;
-use icu_provider::FallbackSupplement;
-mod adapter;
-mod algorithms;
-pub mod provider;
+#[doc(hidden)] // moved
+pub use icu_locid_transform::fallback::{
+ LocaleFallbackIterator, LocaleFallbacker, LocaleFallbackerWithConfig,
+};
+#[doc(hidden)] // moved
+pub use icu_provider::fallback::LocaleFallbackConfig;
-pub use adapter::LocaleFallbackProvider;
-
-use provider::*;
+/// A data provider wrapper that performs locale fallback. This enables arbitrary locales to be
+/// handled at runtime.
+///
+/// # Examples
+///
+/// ```
+/// use icu_locid::locale;
+/// use icu_provider::prelude::*;
+/// use icu_provider::hello_world::*;
+/// use icu_provider_adapters::fallback::LocaleFallbackProvider;
+///
+/// # let provider = icu_provider_blob::BlobDataProvider::try_new_from_static_blob(include_bytes!("../../tests/data/blob.postcard")).unwrap();
+/// # let provider = provider.as_deserializing();
+///
+/// let req = DataRequest {
+/// locale: &locale!("ja-JP").into(),
+/// metadata: Default::default(),
+/// };
+///
+/// // The provider does not have data for "ja-JP":
+/// DataProvider::<HelloWorldV1Marker>::load(&provider, req).expect_err("No fallback");
+///
+/// // But if we wrap the provider in a fallback provider...
+/// let provider = LocaleFallbackProvider::try_new_unstable(provider)
+/// .expect("Fallback data present");
+///
+/// // ...then we can load "ja-JP" based on "ja" data
+/// let response =
+/// DataProvider::<HelloWorldV1Marker>::load(&provider, req).expect("successful with vertical fallback");
+///
+/// assert_eq!(
+/// response.metadata.locale.unwrap(),
+/// locale!("ja").into(),
+/// );
+/// assert_eq!(
+/// response.payload.unwrap().get().message,
+/// "こんにちは世界",
+/// );
+/// ```
+#[derive(Clone, Debug)]
+pub struct LocaleFallbackProvider<P> {
+ inner: P,
+ fallbacker: LocaleFallbacker,
+}
-/// Configuration settings for a particular fallback operation.
-#[derive(Debug, Clone, PartialEq, Eq, Default)]
-#[non_exhaustive]
-pub struct LocaleFallbackConfig {
- /// Strategy for choosing which subtags to drop during locale fallback.
- ///
- /// # Examples
+impl<P> LocaleFallbackProvider<P>
+where
+ P: DataProvider<LocaleFallbackLikelySubtagsV1Marker>
+ + DataProvider<LocaleFallbackParentsV1Marker>
+ + DataProvider<CollationFallbackSupplementV1Marker>,
+{
+ /// Create a [`LocaleFallbackProvider`] by wrapping another data provider and then loading
+ /// fallback data from it.
///
- /// Retain the language and script subtags until the final step:
- ///
- /// ```
- /// use icu_locid::locale;
- /// use icu_provider::prelude::*;
- /// use icu_provider::FallbackPriority;
- /// use icu_provider_adapters::fallback::LocaleFallbackConfig;
- /// use icu_provider_adapters::fallback::LocaleFallbacker;
- ///
- /// // Set up the fallback iterator.
- /// let fallbacker =
- /// LocaleFallbacker::try_new_unstable(&icu_testdata::unstable())
- /// .expect("data");
- /// let mut config = LocaleFallbackConfig::default();
- /// config.priority = FallbackPriority::Language;
- /// let key_fallbacker = fallbacker.for_config(config);
- /// let mut fallback_iterator = key_fallbacker
- /// .fallback_for(DataLocale::from(locale!("ca-ES-valencia")));
- ///
- /// // Run the algorithm and check the results.
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("ca-ES-valencia"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("ca-ES")));
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("ca")));
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("und")));
- /// ```
- ///
- /// Retain the region subtag until the final step:
+ /// If the data provider being wrapped does not contain fallback data, use
+ /// [`LocaleFallbackProvider::new_with_fallbacker`].
+ pub fn try_new_unstable(provider: P) -> Result<Self, DataError> {
+ let fallbacker = LocaleFallbacker::try_new_unstable(&provider)?;
+ Ok(Self {
+ inner: provider,
+ fallbacker,
+ })
+ }
+}
+
+impl<P> LocaleFallbackProvider<P>
+where
+ P: AnyProvider,
+{
+ /// Create a [`LocaleFallbackProvider`] by wrapping another data provider and then loading
+ /// fallback data from it.
///
- /// ```
- /// use icu_locid::locale;
- /// use icu_provider::prelude::*;
- /// use icu_provider::FallbackPriority;
- /// use icu_provider_adapters::fallback::LocaleFallbackConfig;
- /// use icu_provider_adapters::fallback::LocaleFallbacker;
+ /// If the data provider being wrapped does not contain fallback data, use
+ /// [`LocaleFallbackProvider::new_with_fallbacker`].
+ pub fn try_new_with_any_provider(provider: P) -> Result<Self, DataError> {
+ let fallbacker = LocaleFallbacker::try_new_with_any_provider(&provider)?;
+ Ok(Self {
+ inner: provider,
+ fallbacker,
+ })
+ }
+}
+
+#[cfg(feature = "serde")]
+impl<P> LocaleFallbackProvider<P>
+where
+ P: BufferProvider,
+{
+ /// Create a [`LocaleFallbackProvider`] by wrapping another data provider and then loading
+ /// fallback data from it.
///
- /// // Set up the fallback iterator.
- /// let fallbacker =
- /// LocaleFallbacker::try_new_unstable(&icu_testdata::unstable())
- /// .expect("data");
- /// let mut config = LocaleFallbackConfig::default();
- /// config.priority = FallbackPriority::Region;
- /// let key_fallbacker = fallbacker.for_config(config);
- /// let mut fallback_iterator = key_fallbacker
- /// .fallback_for(DataLocale::from(locale!("ca-ES-valencia")));
+ /// If the data provider being wrapped does not contain fallback data, use
+ /// [`LocaleFallbackProvider::new_with_fallbacker`].
+ pub fn try_new_with_buffer_provider(provider: P) -> Result<Self, DataError> {
+ let fallbacker = LocaleFallbacker::try_new_with_buffer_provider(&provider)?;
+ Ok(Self {
+ inner: provider,
+ fallbacker,
+ })
+ }
+}
+
+impl<P> LocaleFallbackProvider<P> {
+ /// Wrap a provider with an arbitrary fallback engine.
///
- /// // Run the algorithm and check the results.
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("ca-ES-valencia"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("ca-ES")));
- /// fallback_iterator.step();
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("und-ES-valencia"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("und-ES"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("und")));
- /// ```
- pub priority: FallbackPriority,
- /// An extension keyword to retain during locale fallback.
+ /// This relaxes the requirement that the wrapped provider contains its own fallback data.
///
/// # Examples
///
/// ```
/// use icu_locid::locale;
+ /// use icu_locid_transform::LocaleFallbacker;
+ /// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
- /// use icu_provider_adapters::fallback::LocaleFallbackConfig;
- /// use icu_provider_adapters::fallback::LocaleFallbacker;
- ///
- /// // Set up the fallback iterator.
- /// let fallbacker =
- /// LocaleFallbacker::try_new_unstable(&icu_testdata::unstable())
- /// .expect("data");
- /// let mut config = LocaleFallbackConfig::default();
- /// config.extension_key = Some(icu_locid::extensions_unicode_key!("nu"));
- /// let key_fallbacker = fallbacker.for_config(config);
- /// let mut fallback_iterator = key_fallbacker
- /// .fallback_for(DataLocale::from(locale!("ar-EG-u-nu-latn")));
- ///
- /// // Run the algorithm and check the results.
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("ar-EG-u-nu-latn"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("ar-EG")));
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("ar")));
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("und")));
- /// ```
- pub extension_key: Option<Key>,
- /// Fallback supplement data key to customize fallback rules.
+ /// use icu_provider_adapters::fallback::LocaleFallbackProvider;
///
- /// For example, most data keys for collation add additional parent locales, such as
- /// "yue" to "zh-Hant", and data used for the `"-u-co"` extension keyword fallback.
+ /// let provider = HelloWorldProvider;
///
- /// Currently the only supported fallback supplement is `FallbackSupplement::Collation`, but more may be
- /// added in the future.
+ /// let req = DataRequest {
+ /// locale: &locale!("de-CH").into(),
+ /// metadata: Default::default(),
+ /// };
///
- /// # Examples
+ /// // There is no "de-CH" data in the `HelloWorldProvider`
+ /// DataProvider::<HelloWorldV1Marker>::load(&provider, req)
+ /// .expect_err("No data for de-CH");
///
- /// ```
- /// use icu_locid::locale;
- /// use icu_provider::prelude::*;
- /// use icu_provider::FallbackPriority;
- /// use icu_provider::FallbackSupplement;
- /// use icu_provider_adapters::fallback::LocaleFallbackConfig;
- /// use icu_provider_adapters::fallback::LocaleFallbacker;
- /// use tinystr::tinystr;
+ /// // `HelloWorldProvider` does not contain fallback data,
+ /// // but we can construct a fallbacker with `icu_locid_transform`'s
+ /// // compiled data.
+ /// let provider = LocaleFallbackProvider::new_with_fallbacker(
+ /// provider,
+ /// LocaleFallbacker::new().static_to_owned(),
+ /// );
///
- /// // Set up the fallback iterator.
- /// let fallbacker =
- /// LocaleFallbacker::try_new_unstable(&icu_testdata::unstable())
- /// .expect("data");
- /// let mut config = LocaleFallbackConfig::default();
- /// config.priority = FallbackPriority::Collation;
- /// config.fallback_supplement = Some(FallbackSupplement::Collation);
- /// let key_fallbacker = fallbacker.for_config(config);
- /// let mut fallback_iterator =
- /// key_fallbacker.fallback_for(DataLocale::from(locale!("yue-HK")));
+ /// // Now we can load the "de-CH" data via fallback to "de".
+ /// let german_hello_world: DataPayload<HelloWorldV1Marker> = provider
+ /// .load(req)
+ /// .expect("Loading should succeed")
+ /// .take_payload()
+ /// .expect("Data should be present");
///
- /// // Run the algorithm and check the results.
- /// // TODO(#1964): add "zh" as a target.
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("yue-HK"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("yue")));
- /// fallback_iterator.step();
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("zh-Hant"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("und")));
+ /// assert_eq!("Hallo Welt", german_hello_world.get().message);
/// ```
- pub fallback_supplement: Option<FallbackSupplement>,
-}
-
-/// Entry type for locale fallbacking.
-///
-/// See the module-level documentation for an example.
-#[derive(Debug, Clone, PartialEq)]
-pub struct LocaleFallbacker {
- likely_subtags: DataPayload<LocaleFallbackLikelySubtagsV1Marker>,
- parents: DataPayload<LocaleFallbackParentsV1Marker>,
- collation_supplement: Option<DataPayload<CollationFallbackSupplementV1Marker>>,
-}
+ pub fn new_with_fallbacker(provider: P, fallbacker: LocaleFallbacker) -> Self {
+ Self {
+ inner: provider,
+ fallbacker,
+ }
+ }
-/// Intermediate type for spawning locale fallback iterators based on a specific configuration.
-///
-/// See the module-level documentation for an example.
-#[derive(Debug, Clone, PartialEq)]
-pub struct LocaleFallbackerWithConfig<'a> {
- likely_subtags: &'a LocaleFallbackLikelySubtagsV1<'a>,
- parents: &'a LocaleFallbackParentsV1<'a>,
- supplement: Option<&'a LocaleFallbackSupplementV1<'a>>,
- config: LocaleFallbackConfig,
-}
+ /// Returns a reference to the inner provider, bypassing fallback.
+ pub fn inner(&self) -> &P {
+ &self.inner
+ }
-/// Inner iteration type. Does not own the item under fallback.
-#[derive(Debug)]
-struct LocaleFallbackIteratorInner<'a, 'b> {
- likely_subtags: &'a LocaleFallbackLikelySubtagsV1<'a>,
- parents: &'a LocaleFallbackParentsV1<'a>,
- supplement: Option<&'a LocaleFallbackSupplementV1<'a>>,
- config: &'b LocaleFallbackConfig,
- backup_extension: Option<Value>,
- backup_subdivision: Option<Value>,
- backup_variants: Option<Variants>,
-}
+ /// Returns a mutable reference to the inner provider.
+ pub fn inner_mut(&mut self) -> &mut P {
+ &mut self.inner
+ }
-/// Iteration type for locale fallback operations.
-///
-/// Because the `Iterator` trait does not allow items to borrow from the iterator, this class does
-/// not implement that trait. Instead, use `.step()` and `.get()`.
-#[derive(Debug)]
-pub struct LocaleFallbackIterator<'a, 'b> {
- current: DataLocale,
- inner: LocaleFallbackIteratorInner<'a, 'b>,
-}
+ /// Returns ownership of the inner provider to the caller.
+ pub fn into_inner(self) -> P {
+ self.inner
+ }
-impl LocaleFallbacker {
- /// Creates a [`LocaleFallbacker`] with fallback data (likely subtags and parent locales).
+ /// Run the fallback algorithm with the data request using the inner data provider.
+ /// Internal function; external clients should use one of the trait impls below.
///
- /// [📚 Help choosing a constructor](icu_provider::constructors)
- /// <div class="stab unstable">
- /// ⚠️ The bounds on this function may change over time, including in SemVer minor releases.
- /// </div>
- pub fn try_new_unstable<P>(provider: &P) -> Result<Self, DataError>
+ /// Function arguments:
+ ///
+ /// - F1 should perform a data load for a single DataRequest and return the result of it
+ /// - F2 should map from the provider-specific response type to DataResponseMetadata
+ fn run_fallback<F1, F2, R>(
+ &self,
+ key: DataKey,
+ mut base_req: DataRequest,
+ mut f1: F1,
+ mut f2: F2,
+ ) -> Result<R, DataError>
where
- P: DataProvider<LocaleFallbackLikelySubtagsV1Marker>
- + DataProvider<LocaleFallbackParentsV1Marker>
- + DataProvider<CollationFallbackSupplementV1Marker>
- + ?Sized,
+ F1: FnMut(DataRequest) -> Result<R, DataError>,
+ F2: FnMut(&mut R) -> &mut DataResponseMetadata,
{
- let likely_subtags = provider.load(Default::default())?.take_payload()?;
- let parents = provider.load(Default::default())?.take_payload()?;
- let collation_supplement = match DataProvider::<CollationFallbackSupplementV1Marker>::load(
- provider,
- Default::default(),
- ) {
- Ok(response) => Some(response.take_payload()?),
- // It is expected that not all keys are present
- Err(DataError {
- kind: DataErrorKind::MissingDataKey,
- ..
- }) => None,
- Err(e) => return Err(e),
- };
- Ok(LocaleFallbacker {
- likely_subtags,
- parents,
- collation_supplement,
- })
- }
-
- icu_provider::gen_any_buffer_constructors!(locale: skip, options: skip, error: DataError);
-
- /// Creates a [`LocaleFallbacker`] without fallback data. Using this constructor may result in
- /// surprising behavior, especially in multi-script languages.
- pub fn new_without_data() -> Self {
- LocaleFallbacker {
- likely_subtags: DataPayload::from_owned(Default::default()),
- parents: DataPayload::from_owned(Default::default()),
- collation_supplement: None,
+ if key.metadata().singleton {
+ return f1(base_req);
}
- }
-
- /// Creates the intermediate [`LocaleFallbackerWithConfig`] with configuration options.
- pub fn for_config(&self, config: LocaleFallbackConfig) -> LocaleFallbackerWithConfig {
- let supplement = match config.fallback_supplement {
- Some(FallbackSupplement::Collation) => {
- self.collation_supplement.as_ref().map(|p| p.get())
+ let mut fallback_iterator = self
+ .fallbacker
+ .for_config(key.fallback_config())
+ .fallback_for(base_req.locale.clone());
+ let base_silent = core::mem::replace(&mut base_req.metadata.silent, true);
+ loop {
+ let result = f1(DataRequest {
+ locale: fallback_iterator.get(),
+ metadata: base_req.metadata,
+ });
+ if !result_is_err_missing_locale(&result) {
+ return result
+ .map(|mut res| {
+ f2(&mut res).locale = Some(fallback_iterator.take());
+ res
+ })
+ // Log the original request rather than the fallback request
+ .map_err(|e| {
+ base_req.metadata.silent = base_silent;
+ e.with_req(key, base_req)
+ });
+ }
+ // If we just checked und, break out of the loop.
+ if fallback_iterator.get().is_und() {
+ break;
}
- _ => None,
- };
- LocaleFallbackerWithConfig {
- likely_subtags: self.likely_subtags.get(),
- parents: self.parents.get(),
- supplement,
- config,
+ fallback_iterator.step();
}
- }
-
- /// Creates the intermediate [`LocaleFallbackerWithConfig`] based on a
- /// [`DataKey`] and a [`DataRequestMetadata`].
- ///
- /// # Examples
- ///
- /// ```
- /// use icu_locid::locale;
- /// use icu_provider::prelude::*;
- /// use icu_provider_adapters::fallback::LocaleFallbacker;
- /// use std::borrow::Cow;
- ///
- /// // Define the data struct with key.
- /// #[icu_provider::data_struct(marker(
- /// FooV1Marker,
- /// "demo/foo@1",
- /// fallback_by = "region"
- /// ))]
- /// pub struct FooV1<'data> {
- /// message: Cow<'data, str>,
- /// };
- ///
- /// // Set up the fallback iterator.
- /// let fallbacker =
- /// LocaleFallbacker::try_new_unstable(&icu_testdata::unstable())
- /// .expect("data");
- /// let key_fallbacker = fallbacker.for_key(FooV1Marker::KEY);
- /// let mut fallback_iterator =
- /// key_fallbacker.fallback_for(DataLocale::from(locale!("en-GB")));
- ///
- /// // Run the algorithm and check the results.
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("en-GB")));
- /// fallback_iterator.step();
- /// assert_eq!(
- /// fallback_iterator.get(),
- /// &DataLocale::from(locale!("und-GB"))
- /// );
- /// fallback_iterator.step();
- /// assert_eq!(fallback_iterator.get(), &DataLocale::from(locale!("und")));
- /// ```
- ///
- /// [`DataRequestMetadata`]: icu_provider::DataRequestMetadata
- pub fn for_key(&self, data_key: DataKey) -> LocaleFallbackerWithConfig {
- let priority = data_key.metadata().fallback_priority;
- let extension_key = data_key.metadata().extension_key;
- let fallback_supplement = data_key.metadata().fallback_supplement;
- self.for_config(LocaleFallbackConfig {
- priority,
- extension_key,
- fallback_supplement,
- })
+ base_req.metadata.silent = base_silent;
+ Err(DataErrorKind::MissingLocale.with_req(key, base_req))
}
}
-impl<'a> LocaleFallbackerWithConfig<'a> {
- /// Creates an iterator based on a [`DataLocale`] (which can be created from [`Locale`]).
- ///
- /// When first initialized, the locale is normalized according to the fallback algorithm.
- ///
- /// [`Locale`]: icu_locid::Locale
- pub fn fallback_for<'b>(&'b self, mut locale: DataLocale) -> LocaleFallbackIterator<'a, 'b> {
- self.normalize(&mut locale);
- LocaleFallbackIterator {
- current: locale,
- inner: LocaleFallbackIteratorInner {
- likely_subtags: self.likely_subtags,
- parents: self.parents,
- supplement: self.supplement,
- config: &self.config,
- backup_extension: None,
- backup_subdivision: None,
- backup_variants: None,
- },
- }
+impl<P> AnyProvider for LocaleFallbackProvider<P>
+where
+ P: AnyProvider,
+{
+ fn load_any(&self, key: DataKey, base_req: DataRequest) -> Result<AnyResponse, DataError> {
+ self.run_fallback(
+ key,
+ base_req,
+ |req| self.inner.load_any(key, req),
+ |res| &mut res.metadata,
+ )
}
}
-impl LocaleFallbackIterator<'_, '_> {
- /// Borrows the current [`DataLocale`] under fallback.
- pub fn get(&self) -> &DataLocale {
- &self.current
+impl<P> BufferProvider for LocaleFallbackProvider<P>
+where
+ P: BufferProvider,
+{
+ fn load_buffer(
+ &self,
+ key: DataKey,
+ base_req: DataRequest,
+ ) -> Result<DataResponse<BufferMarker>, DataError> {
+ self.run_fallback(
+ key,
+ base_req,
+ |req| self.inner.load_buffer(key, req),
+ |res| &mut res.metadata,
+ )
}
+}
- /// Takes the current [`DataLocale`] under fallback.
- pub fn take(self) -> DataLocale {
- self.current
+impl<P, M> DynamicDataProvider<M> for LocaleFallbackProvider<P>
+where
+ P: DynamicDataProvider<M>,
+ M: DataMarker,
+{
+ fn load_data(&self, key: DataKey, base_req: DataRequest) -> Result<DataResponse<M>, DataError> {
+ self.run_fallback(
+ key,
+ base_req,
+ |req| self.inner.load_data(key, req),
+ |res| &mut res.metadata,
+ )
}
+}
- /// Performs one step of the locale fallback algorithm.
- ///
- /// The fallback is completed once the inner [`DataLocale`] becomes `und`.
- pub fn step(&mut self) -> &mut Self {
- self.inner.step(&mut self.current);
- self
+impl<P, M> DataProvider<M> for LocaleFallbackProvider<P>
+where
+ P: DataProvider<M>,
+ M: KeyedDataMarker,
+{
+ fn load(&self, base_req: DataRequest) -> Result<DataResponse<M>, DataError> {
+ self.run_fallback(
+ M::KEY,
+ base_req,
+ |req| self.inner.load(req),
+ |res| &mut res.metadata,
+ )
}
}
diff --git a/vendor/icu_provider_adapters/src/fallback/provider.rs b/vendor/icu_provider_adapters/src/fallback/provider.rs
deleted file mode 100644
index edfa01f58..000000000
--- a/vendor/icu_provider_adapters/src/fallback/provider.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-// This file is part of ICU4X. For terms of use, please see the file
-// called LICENSE at the top level of the ICU4X source tree
-// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
-
-//! Data provider struct definitions for vertical fallback.
-//!
-//! Read more about data providers: [`icu_provider`]
-
-// Provider structs must be stable
-#![allow(clippy::exhaustive_structs)]
-
-use icu_locid::extensions::unicode::Key;
-use icu_locid::subtags::{Language, Region, Script};
-use icu_locid::{subtags_region as region, subtags_script as script};
-use tinystr::TinyAsciiStr;
-
-use icu_provider::prelude::*;
-
-use zerovec::ule::UnvalidatedStr;
-use zerovec::ZeroMap;
-use zerovec::ZeroMap2d;
-
-// We use raw TinyAsciiStrs for map keys, as we then don't have to
-// validate them as subtags on deserialization. Map lookup can be
-// done even if they are not valid tags (an invalid key will just
-// become inaccessible).
-type UnvalidatedLanguage = TinyAsciiStr<3>;
-type UnvalidatedScript = TinyAsciiStr<4>;
-type UnvalidatedRegion = TinyAsciiStr<3>;
-
-/// Locale fallback rules derived from likely subtags data.
-#[icu_provider::data_struct(LocaleFallbackLikelySubtagsV1Marker = "fallback/likelysubtags@1")]
-#[derive(Default, Clone, PartialEq, Debug)]
-#[cfg_attr(
- feature = "datagen",
- derive(serde::Serialize, databake::Bake),
- databake(path = icu_provider_adapters::fallback::provider),
-)]
-#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
-#[yoke(prove_covariance_manually)]
-pub struct LocaleFallbackLikelySubtagsV1<'data> {
- /// Map from language to the default script in that language. Languages whose default script
- /// is `Latn` are not included in the map for data size savings.
- ///
- /// Example: "zh" defaults to "Hans", which is in this map.
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub l2s: ZeroMap<'data, UnvalidatedLanguage, Script>,
- /// Map from language-region pairs to a script. Only populated if the script is different
- /// from the one in `l2s` for that language.
- ///
- /// Example: "zh-TW" defaults to "Hant", which is in this map.
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub lr2s: ZeroMap2d<'data, UnvalidatedLanguage, UnvalidatedRegion, Script>,
- /// Map from language to the default region in that language. Languages whose default region
- /// is `ZZ` are not included in the map for data size savings.
- ///
- /// Example: "zh" defaults to "CN".
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub l2r: ZeroMap<'data, UnvalidatedLanguage, Region>,
- /// Map from language-script pairs to a region. Only populated if the region is different
- /// from the one in `l2r` for that language.
- ///
- /// Example: "zh-Hant" defaults to "TW".
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub ls2r: ZeroMap2d<'data, UnvalidatedLanguage, UnvalidatedScript, Region>,
-}
-
-/// `Latn` is the most common script, so it is defaulted for data size savings.
-pub const DEFAULT_SCRIPT: Script = script!("Latn");
-
-/// `ZZ` is the most common region, so it is defaulted for data size savings.
-pub const DEFAULT_REGION: Region = region!("ZZ");
-
-/// Locale fallback rules derived from CLDR parent locales data.
-#[icu_provider::data_struct(LocaleFallbackParentsV1Marker = "fallback/parents@1")]
-#[derive(Default, Clone, PartialEq, Debug)]
-#[cfg_attr(
- feature = "datagen",
- derive(serde::Serialize, databake::Bake),
- databake(path = icu_provider_adapters::fallback::provider),
-)]
-#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
-#[yoke(prove_covariance_manually)]
-pub struct LocaleFallbackParentsV1<'data> {
- /// Map from language identifier to language identifier, indicating that the language on the
- /// left should inherit from the language on the right.
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub parents: ZeroMap<'data, UnvalidatedStr, (Language, Option<Script>, Option<Region>)>,
-}
-
-/// Key-specific supplemental fallback data.
-#[icu_provider::data_struct(marker(
- CollationFallbackSupplementV1Marker,
- "fallback/supplement/co@1"
-))]
-#[derive(Default, Clone, PartialEq, Debug)]
-#[cfg_attr(
- feature = "datagen",
- derive(serde::Serialize, databake::Bake),
- databake(path = icu_provider_adapters::fallback::provider),
-)]
-#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
-#[yoke(prove_covariance_manually)]
-pub struct LocaleFallbackSupplementV1<'data> {
- /// Additional parent locales to supplement the common ones.
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub parents: ZeroMap<'data, UnvalidatedStr, (Language, Option<Script>, Option<Region>)>,
- /// Default values for Unicode extension keywords.
- #[cfg_attr(feature = "serde", serde(borrow))]
- pub unicode_extension_defaults: ZeroMap2d<'data, Key, UnvalidatedStr, UnvalidatedStr>,
-}
diff --git a/vendor/icu_provider_adapters/src/filter/impls.rs b/vendor/icu_provider_adapters/src/filter/impls.rs
index df18cf72c..f24248eff 100644
--- a/vendor/icu_provider_adapters/src/filter/impls.rs
+++ b/vendor/icu_provider_adapters/src/filter/impls.rs
@@ -25,7 +25,7 @@ where
///
/// ```
/// use icu_locid::LanguageIdentifier;
- /// use icu_locid::{langid, locale, subtags_language as language};
+ /// use icu_locid::{langid, locale, subtags::language};
/// use icu_provider::datagen::*;
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
@@ -106,7 +106,7 @@ where
/// use icu_provider::prelude::*;
/// use icu_provider_adapters::filter::Filterable;
///
- /// let allowlist = vec![langid!("de"), langid!("zh")];
+ /// let allowlist = [langid!("de"), langid!("zh")];
/// let provider = HelloWorldProvider
/// .filterable("Demo German+Chinese filter")
/// .filter_by_langid_allowlist_strict(&allowlist);
diff --git a/vendor/icu_provider_adapters/src/filter/mod.rs b/vendor/icu_provider_adapters/src/filter/mod.rs
index 83be9f779..19b6bf233 100644
--- a/vendor/icu_provider_adapters/src/filter/mod.rs
+++ b/vendor/icu_provider_adapters/src/filter/mod.rs
@@ -21,7 +21,7 @@
//! # Examples
//!
//! ```
-//! use icu_locid::subtags_language as language;
+//! use icu_locid::subtags::language;
//! use icu_provider::hello_world::*;
//! use icu_provider::prelude::*;
//! use icu_provider_adapters::filter::Filterable;
diff --git a/vendor/icu_provider_adapters/src/fork/by_error.rs b/vendor/icu_provider_adapters/src/fork/by_error.rs
index aae996761..5d25ce207 100644
--- a/vendor/icu_provider_adapters/src/fork/by_error.rs
+++ b/vendor/icu_provider_adapters/src/fork/by_error.rs
@@ -174,7 +174,7 @@ where
key: DataKey,
req: DataRequest,
) -> Result<DataResponse<BufferMarker>, DataError> {
- let mut last_error = DataErrorKind::MissingDataKey.with_key(key);
+ let mut last_error = F::UNIT_ERROR.with_key(key);
for provider in self.providers.iter() {
let result = provider.load_buffer(key, req);
match result {
@@ -193,7 +193,7 @@ where
F: ForkByErrorPredicate,
{
fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> {
- let mut last_error = DataErrorKind::MissingDataKey.with_key(key);
+ let mut last_error = F::UNIT_ERROR.with_key(key);
for provider in self.providers.iter() {
let result = provider.load_any(key, req);
match result {
@@ -213,7 +213,7 @@ where
F: ForkByErrorPredicate,
{
fn load_data(&self, key: DataKey, req: DataRequest) -> Result<DataResponse<M>, DataError> {
- let mut last_error = DataErrorKind::MissingDataKey.with_key(key);
+ let mut last_error = F::UNIT_ERROR.with_key(key);
for provider in self.providers.iter() {
let result = provider.load_data(key, req);
match result {
@@ -234,7 +234,7 @@ where
F: ForkByErrorPredicate,
{
fn supported_locales_for_key(&self, key: DataKey) -> Result<Vec<DataLocale>, DataError> {
- let mut last_error = DataErrorKind::MissingDataKey.with_key(key);
+ let mut last_error = F::UNIT_ERROR.with_key(key);
for provider in self.providers.iter() {
let result = provider.supported_locales_for_key(key);
match result {
@@ -260,7 +260,7 @@ where
key: DataKey,
mut from: DataPayload<MFrom>,
) -> Result<DataPayload<MTo>, (DataPayload<MFrom>, DataError)> {
- let mut last_error = DataErrorKind::MissingDataKey.with_key(key);
+ let mut last_error = F::UNIT_ERROR.with_key(key);
for provider in self.providers.iter() {
let result = provider.convert(key, from);
match result {
diff --git a/vendor/icu_provider_adapters/src/fork/macros.rs b/vendor/icu_provider_adapters/src/fork/macros.rs
index 7c18a9ba3..eb98ec693 100644
--- a/vendor/icu_provider_adapters/src/fork/macros.rs
+++ b/vendor/icu_provider_adapters/src/fork/macros.rs
@@ -11,27 +11,23 @@
/// use icu_provider_adapters::fork::ForkByKeyProvider;
///
/// // Some empty example providers:
-/// #[derive(Default, PartialEq, Debug)]
+/// #[derive(PartialEq, Debug)]
/// struct Provider1;
-/// #[derive(Default, PartialEq, Debug)]
+/// #[derive(PartialEq, Debug)]
/// struct Provider2;
-/// #[derive(Default, PartialEq, Debug)]
+/// #[derive(PartialEq, Debug)]
/// struct Provider3;
///
/// // Combine them into one:
/// let forking1 = icu_provider_adapters::make_forking_provider!(
/// ForkByKeyProvider::new,
-/// [
-/// Provider1::default(),
-/// Provider2::default(),
-/// Provider3::default(),
-/// ]
+/// [Provider1, Provider2, Provider3,]
/// );
///
/// // This is equivalent to:
/// let forking2 = ForkByKeyProvider::new(
-/// Provider1::default(),
-/// ForkByKeyProvider::new(Provider2::default(), Provider3::default()),
+/// Provider1,
+/// ForkByKeyProvider::new(Provider2, Provider3),
/// );
///
/// assert_eq!(forking1, forking2);
@@ -50,22 +46,15 @@ macro_rules! make_forking_provider {
#[cfg(test)]
mod test {
- #[derive(Default)]
struct Provider1;
- #[derive(Default)]
struct Provider2;
- #[derive(Default)]
struct Provider3;
#[test]
fn test_make_forking_provider() {
make_forking_provider!(
crate::fork::ForkByKeyProvider::new,
- [
- Provider1::default(),
- Provider2::default(),
- Provider3::default(),
- ]
+ [Provider1, Provider2, Provider3,]
);
}
}
diff --git a/vendor/icu_provider_adapters/src/fork/mod.rs b/vendor/icu_provider_adapters/src/fork/mod.rs
index 05ba5fd19..a15c742c6 100644
--- a/vendor/icu_provider_adapters/src/fork/mod.rs
+++ b/vendor/icu_provider_adapters/src/fork/mod.rs
@@ -80,9 +80,9 @@ use predicates::MissingDataKeyPredicate;
/// HelloWorldProvider.into_json_provider(),
/// );
///
-/// let data_provider = forking_provider.as_deserializing();
+/// let provider = forking_provider.as_deserializing();
///
-/// let german_hello_world: DataPayload<HelloWorldV1Marker> = data_provider
+/// let german_hello_world: DataPayload<HelloWorldV1Marker> = provider
/// .load(DataRequest {
/// locale: &locale!("de").into(),
/// metadata: Default::default(),
@@ -97,7 +97,7 @@ use predicates::MissingDataKeyPredicate;
/// Stops at the first provider supporting a key, even if the locale is not supported:
///
/// ```
-/// use icu_locid::{subtags_language as language, locale};
+/// use icu_locid::{subtags::language, locale};
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
/// use icu_provider_adapters::filter::Filterable;
@@ -114,11 +114,11 @@ use predicates::MissingDataKeyPredicate;
/// .filter_by_langid(|langid| langid.language == language!("de")),
/// );
///
-/// let data_provider: &dyn DataProvider<HelloWorldV1Marker> =
+/// let provider: &dyn DataProvider<HelloWorldV1Marker> =
/// &forking_provider.as_deserializing();
///
/// // Chinese is the first provider, so this succeeds
-/// let chinese_hello_world = data_provider
+/// let chinese_hello_world = provider
/// .load(DataRequest {
/// locale: &locale!("zh").into(),
/// metadata: Default::default(),
@@ -130,7 +130,7 @@ use predicates::MissingDataKeyPredicate;
/// assert_eq!("你好世界", chinese_hello_world.get().message);
///
/// // German is shadowed by Chinese, so this fails
-/// data_provider
+/// provider
/// .load(DataRequest {
/// locale: &locale!("de").into(),
/// metadata: Default::default(),
@@ -166,7 +166,7 @@ impl<P0, P1> ForkByKeyProvider<P0, P1> {
/// # Examples
///
/// ```
-/// use icu_locid::{subtags_language as language, locale};
+/// use icu_locid::{subtags::language, locale};
/// use icu_provider::hello_world::*;
/// use icu_provider::prelude::*;
/// use icu_provider_adapters::filter::Filterable;
@@ -185,11 +185,11 @@ impl<P0, P1> ForkByKeyProvider<P0, P1> {
/// ],
/// );
///
-/// let data_provider: &dyn DataProvider<HelloWorldV1Marker> =
+/// let provider: &dyn DataProvider<HelloWorldV1Marker> =
/// &forking_provider.as_deserializing();
///
/// // Chinese is the first provider, so this succeeds
-/// let chinese_hello_world = data_provider
+/// let chinese_hello_world = provider
/// .load(DataRequest {
/// locale: &locale!("zh").into(),
/// metadata: Default::default(),
@@ -201,7 +201,7 @@ impl<P0, P1> ForkByKeyProvider<P0, P1> {
/// assert_eq!("你好世界", chinese_hello_world.get().message);
///
/// // German is shadowed by Chinese, so this fails
-/// data_provider
+/// provider
/// .load(DataRequest {
/// locale: &locale!("de").into(),
/// metadata: Default::default(),
diff --git a/vendor/icu_provider_adapters/src/fork/predicates.rs b/vendor/icu_provider_adapters/src/fork/predicates.rs
index 0fefe5704..58ffa7416 100644
--- a/vendor/icu_provider_adapters/src/fork/predicates.rs
+++ b/vendor/icu_provider_adapters/src/fork/predicates.rs
@@ -10,6 +10,9 @@ use icu_provider::prelude::*;
///
/// [`ForkByErrorProvider`]: super::ForkByErrorProvider
pub trait ForkByErrorPredicate {
+ /// The error to return if there are zero providers.
+ const UNIT_ERROR: DataErrorKind = DataErrorKind::MissingDataKey;
+
/// This function is called when a data request fails and there are additional providers
/// that could possibly fulfill the request.
///
@@ -43,6 +46,8 @@ pub trait ForkByErrorPredicate {
pub struct MissingDataKeyPredicate;
impl ForkByErrorPredicate for MissingDataKeyPredicate {
+ const UNIT_ERROR: DataErrorKind = DataErrorKind::MissingDataKey;
+
#[inline]
fn test(&self, _: DataKey, _: Option<DataRequest>, err: DataError) -> bool {
matches!(
@@ -125,6 +130,8 @@ impl ForkByErrorPredicate for MissingDataKeyPredicate {
pub struct MissingLocalePredicate;
impl ForkByErrorPredicate for MissingLocalePredicate {
+ const UNIT_ERROR: DataErrorKind = DataErrorKind::MissingLocale;
+
#[inline]
fn test(&self, _: DataKey, _: Option<DataRequest>, err: DataError) -> bool {
matches!(
diff --git a/vendor/icu_provider_adapters/tests/data/blob.postcard b/vendor/icu_provider_adapters/tests/data/blob.postcard
new file mode 100644
index 000000000..c958c7bfd
--- /dev/null
+++ b/vendor/icu_provider_adapters/tests/data/blob.postcard
Binary files differ
diff --git a/vendor/icu_provider_adapters/tests/data/config.json b/vendor/icu_provider_adapters/tests/data/config.json
new file mode 100644
index 000000000..db3a07ac1
--- /dev/null
+++ b/vendor/icu_provider_adapters/tests/data/config.json
@@ -0,0 +1,21 @@
+{
+ "keys": {
+ "explicit": [
+ "core/helloworld@1",
+ "fallback/likelysubtags@1",
+ "fallback/parents@1",
+ "fallback/supplement/co@1"
+ ]
+ },
+ "fallback": "runtimeManual",
+ "locales": "all",
+ "cldr": "latest",
+ "icuExport": "none",
+ "segmenterLstm": "none",
+ "export": {
+ "blob": {
+ "path": "blob.postcard"
+ }
+ },
+ "overwrite": true
+} \ No newline at end of file
diff --git a/vendor/icu_provider_adapters/tests/data/langtest/de.json b/vendor/icu_provider_adapters/tests/data/langtest/de.json
new file mode 100644
index 000000000..8c69fa425
--- /dev/null
+++ b/vendor/icu_provider_adapters/tests/data/langtest/de.json
@@ -0,0 +1,23 @@
+{
+ "keys": {
+ "explicit": [
+ "core/helloworld@1"
+ ]
+ },
+ "fallback": "preresolved",
+ "locales": {
+ "explicit": [
+ "de"
+ ]
+ },
+ "cldr": "none",
+ "icuExport": "none",
+ "segmenterLstm": "none",
+ "export": {
+ "fileSystem": {
+ "path": "de",
+ "syntax": "json"
+ }
+ },
+ "overwrite": true
+} \ No newline at end of file
diff --git a/vendor/icu_provider_adapters/tests/data/langtest/ro.json b/vendor/icu_provider_adapters/tests/data/langtest/ro.json
new file mode 100644
index 000000000..afae9e85a
--- /dev/null
+++ b/vendor/icu_provider_adapters/tests/data/langtest/ro.json
@@ -0,0 +1,23 @@
+{
+ "keys": {
+ "explicit": [
+ "core/helloworld@1"
+ ]
+ },
+ "fallback": "preresolved",
+ "locales": {
+ "explicit": [
+ "ro"
+ ]
+ },
+ "cldr": "none",
+ "icuExport": "none",
+ "segmenterLstm": "none",
+ "export": {
+ "fileSystem": {
+ "path": "ro",
+ "syntax": "json"
+ }
+ },
+ "overwrite": true
+} \ No newline at end of file