1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5//! `icu_provider` is one of the [`ICU4X`] components.
6//!
7//! Unicode's experience with ICU4X's parent projects, ICU4C and ICU4J, led the team to realize
8//! that data management is the most critical aspect of deploying internationalization, and that it requires
9//! a high level of customization for the needs of the platform it is embedded in. As a result
10//! ICU4X comes with a selection of providers that should allow for ICU4X to naturally fit into
11//! different business and technological needs of customers.
12//!
13//! `icu_provider` defines traits and structs for transmitting data through the ICU4X locale
14//! data pipeline. The primary trait is [`DataProvider`]. It is parameterized by a
15//! [`KeyedDataMarker`], which contains the data type and a [`DataKey`]. It has one method,
16//! [`DataProvider::load`], which transforms a [`DataRequest`]
17//! into a [`DataResponse`].
18//!
19//! - [`DataKey`] is a fixed identifier for the data type, such as `"plurals/cardinal@1"`.
20//! - [`DataRequest`] contains additional annotations to choose a specific variant of the key,
21//! such as a locale.
22//! - [`DataResponse`] contains the data if the request was successful.
23//!
24//! In addition, there are three other traits which are widely implemented:
25//!
26//! - [`AnyProvider`] returns data as `dyn Any` trait objects.
27//! - [`BufferProvider`] returns data as `[u8]` buffers.
28//! - [`DynamicDataProvider`] returns structured data but is not specific to a key.
29//!
30//! The most common types required for this crate are included via the prelude:
31//!
32//! ```
33//! use icu_provider::prelude::*;
34//! ```
35//!
36//! ## Types of Data Providers
37//!
38//! All nontrivial data providers can fit into one of two classes.
39//!
40//! 1. [`AnyProvider`]: Those whose data originates as structured Rust objects
41//! 2. [`BufferProvider`]: Those whose data originates as unstructured `[u8]` buffers
42//!
43//! **✨ Key Insight:** A given data provider is generally *either* an [`AnyProvider`] *or* a
44//! [`BufferProvider`]. Which type depends on the data source, and it is not generally possible
45//! to convert one to the other.
46//!
47//! See also [crate::constructors].
48//!
49//! ### AnyProvider
50//!
51//! These providers are able to return structured data cast into `dyn Any` trait objects. Users
52//! can call [`as_downcasting()`] to get an object implementing [`DataProvider`] by downcasting
53//! the trait objects.
54//!
55//! Examples of AnyProviders:
56//!
57//! - [`DatagenProvider`] reads structured data from CLDR source files and returns ICU4X data structs.
58//! - [`AnyPayloadProvider`] wraps a specific data struct and returns it.
59//! - The `BakedDataProvider` which encodes structured data directly in Rust source
60//!
61//! ### BufferProvider
62//!
63//! These providers are able to return unstructured data typically represented as
64//! [`serde`]-serialized buffers. Users can call [`as_deserializing()`] to get an object
65//! implementing [`DataProvider`] by invoking Serde Deserialize.
66//!
67//! Examples of BufferProviders:
68//!
69//! - [`FsDataProvider`] reads individual buffers from the filesystem.
70//! - [`BlobDataProvider`] reads buffers from a large in-memory blob.
71//!
72//! ## Provider Adapters
73//!
74//! ICU4X offers several built-in modules to combine providers in interesting ways.
75//! These can be found in the [`icu_provider_adapters`] crate.
76//!
77//! ## Testing Provider
78//!
79//! This crate also contains a concrete provider for demonstration purposes:
80//!
81//! - [`HelloWorldProvider`] returns "hello world" strings in several languages.
82//!
83//! ## Types and Lifetimes
84//!
85//! Types compatible with [`Yokeable`] can be passed through the data provider, so long as they are
86//! associated with a marker type implementing [`DataMarker`].
87//!
88//! Data structs should generally have one lifetime argument: `'data`. This lifetime allows data
89//! structs to borrow zero-copy data.
90//!
91//! ## Data generation API
92//!
93//! *This functionality is enabled with the "datagen" Cargo feature*
94//!
95//! The [`datagen`] module contains several APIs for data generation. See [`icu_datagen`] for the reference
96//! data generation implementation.
97//!
98//! [`ICU4X`]: ../icu/index.html
99//! [`DataProvider`]: data_provider::DataProvider
100//! [`DataKey`]: key::DataKey
101//! [`DataLocale`]: request::DataLocale
102//! [`IterableDynamicDataProvider`]: datagen::IterableDynamicDataProvider
103//! [`IterableDataProvider`]: datagen::IterableDataProvider
104//! [`AnyPayloadProvider`]: ../icu_provider_adapters/any_payload/struct.AnyPayloadProvider.html
105//! [`HelloWorldProvider`]: hello_world::HelloWorldProvider
106//! [`AnyProvider`]: any::AnyProvider
107//! [`Yokeable`]: yoke::Yokeable
108//! [`impl_dynamic_data_provider!`]: impl_dynamic_data_provider
109//! [`icu_provider_adapters`]: ../icu_provider_adapters/index.html
110//! [`DatagenProvider`]: ../icu_datagen/struct.DatagenProvider.html
111//! [`as_downcasting()`]: AsDowncastingAnyProvider::as_downcasting
112//! [`as_deserializing()`]: AsDeserializingBufferProvider::as_deserializing
113//! [`CldrJsonDataProvider`]: ../icu_datagen/cldr/struct.CldrJsonDataProvider.html
114//! [`FsDataProvider`]: ../icu_provider_fs/struct.FsDataProvider.html
115//! [`BlobDataProvider`]: ../icu_provider_blob/struct.BlobDataProvider.html
116//! [`icu_datagen`]: ../icu_datagen/index.html
117
118// https://github.com/unicode-org/icu4x/blob/main/docs/process/boilerplate.md#library-annotations
119#![cfg_attr(not(any(test, feature = "std")), no_std)]
120#![cfg_attr(
121 not(test),
122 deny(
123 clippy::indexing_slicing,
124 clippy::unwrap_used,
125 clippy::expect_used,
126 clippy::panic,
127 clippy::exhaustive_structs,
128 clippy::exhaustive_enums,
129 missing_debug_implementations,
130 )
131)]
132#![warn(missing_docs)]
133
134extern crate alloc;
135
136mod data_provider;
137mod error;
138#[doc(hidden)]
139pub mod fallback;
140mod key;
141mod request;
142mod response;
143
144pub mod any;
145pub mod buf;
146pub mod constructors;
147#[cfg(feature = "datagen")]
148pub mod datagen;
149pub mod dynutil;
150pub mod hello_world;
151pub mod marker;
152#[cfg(feature = "serde")]
153pub mod serde;
154
155// Types from private modules
156pub use crate::data_provider::DataProvider;
157pub use crate::data_provider::DynamicDataProvider;
158pub use crate::error::DataError;
159pub use crate::error::DataErrorKind;
160pub use crate::key::DataKey;
161pub use crate::key::DataKeyHash;
162pub use crate::key::DataKeyMetadata;
163pub use crate::key::DataKeyPath;
164#[cfg(feature = "experimental")]
165pub use crate::request::AuxiliaryKeys;
166pub use crate::request::DataLocale;
167pub use crate::request::DataRequest;
168pub use crate::request::DataRequestMetadata;
169pub use crate::response::Cart;
170pub use crate::response::DataPayload;
171pub use crate::response::DataResponse;
172pub use crate::response::DataResponseMetadata;
173#[cfg(feature = "macros")]
174pub use icu_provider_macros::data_struct;
175
176// Reexports from public modules
177pub use crate::any::AnyMarker;
178pub use crate::any::AnyPayload;
179pub use crate::any::AnyProvider;
180pub use crate::any::AnyResponse;
181pub use crate::any::AsDowncastingAnyProvider;
182pub use crate::any::AsDynamicDataProviderAnyMarkerWrap;
183pub use crate::any::MaybeSendSync;
184pub use crate::buf::BufferMarker;
185pub use crate::buf::BufferProvider;
186pub use crate::marker::DataMarker;
187pub use crate::marker::KeyedDataMarker;
188#[cfg(feature = "serde")]
189pub use crate::serde::AsDeserializingBufferProvider;
190
191/// Core selection of APIs and structures for the ICU4X data provider.
192pub mod prelude {
193 #[doc(no_inline)]
194 pub use crate::data_key;
195 #[doc(no_inline)]
196 pub use crate::AnyMarker;
197 #[doc(no_inline)]
198 pub use crate::AnyPayload;
199 #[doc(no_inline)]
200 pub use crate::AnyProvider;
201 #[doc(no_inline)]
202 pub use crate::AnyResponse;
203 #[doc(no_inline)]
204 #[cfg(feature = "serde")]
205 pub use crate::AsDeserializingBufferProvider;
206 #[doc(no_inline)]
207 pub use crate::AsDowncastingAnyProvider;
208 #[doc(no_inline)]
209 pub use crate::AsDynamicDataProviderAnyMarkerWrap;
210 #[doc(no_inline)]
211 #[cfg(feature = "experimental")]
212 pub use crate::AuxiliaryKeys;
213 #[doc(no_inline)]
214 pub use crate::BufferMarker;
215 #[doc(no_inline)]
216 pub use crate::BufferProvider;
217 #[doc(no_inline)]
218 pub use crate::DataError;
219 #[doc(no_inline)]
220 pub use crate::DataErrorKind;
221 #[doc(no_inline)]
222 pub use crate::DataKey;
223 #[doc(no_inline)]
224 pub use crate::DataKeyHash;
225 #[doc(no_inline)]
226 pub use crate::DataLocale;
227 #[doc(no_inline)]
228 pub use crate::DataMarker;
229 #[doc(no_inline)]
230 pub use crate::DataPayload;
231 #[doc(no_inline)]
232 pub use crate::DataProvider;
233 #[doc(no_inline)]
234 pub use crate::DataRequest;
235 #[doc(no_inline)]
236 pub use crate::DataRequestMetadata;
237 #[doc(no_inline)]
238 pub use crate::DataResponse;
239 #[doc(no_inline)]
240 pub use crate::DataResponseMetadata;
241 #[doc(no_inline)]
242 pub use crate::DynamicDataProvider;
243 #[doc(no_inline)]
244 pub use crate::KeyedDataMarker;
245
246 #[doc(hidden)]
247 pub use yoke;
248 #[doc(hidden)]
249 pub use zerofrom;
250}
251
252// Additional crate re-exports for compatibility
253#[doc(hidden)]
254pub use fallback::LocaleFallbackPriority as FallbackPriority;
255#[doc(hidden)]
256pub use fallback::LocaleFallbackSupplement as FallbackSupplement;
257#[doc(hidden)]
258pub use yoke;
259#[doc(hidden)]
260pub use zerofrom;
261
262// For macros
263#[doc(hidden)]
264pub mod _internal {
265 pub use super::fallback::{LocaleFallbackPriority, LocaleFallbackSupplement};
266 pub use icu_locid as locid;
267}
268