]>
Commit | Line | Data |
---|---|---|
487cf647 FG |
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 | //! 📚 *This module documents ICU4X constructor signatures.* | |
6 | //! | |
7 | //! One of the key differences between ICU4X and its parent projects, ICU4C and ICU4J, is in how | |
8 | //! it deals with locale data. | |
9 | //! | |
10 | //! In ICU4X, the data provider is an *explicit argument* whenever it is required by the library. | |
11 | //! This enables ICU4X to achieve the following value propositions: | |
12 | //! | |
13 | //! 1. Configurable data sources (machine-readable data file, baked into code, JSON, etc). | |
14 | //! 2. Dynamic data loading at runtime (load data on demand). | |
15 | //! 3. Reduced overhead and code size (data is resolved locally at each call site). | |
16 | //! 4. Explicit support for multiple ICU4X instances sharing data. | |
17 | //! | |
18 | //! In order to achieve these goals, there are 3 versions of all Rust ICU4X functions that | |
19 | //! take a data provider argument: | |
20 | //! | |
21 | //! 1. `*_unstable` | |
22 | //! 2. `*_with_any_provider` | |
23 | //! 3. `*_with_buffer_provider` | |
24 | //! | |
25 | //! # Which constructor should I use? | |
26 | //! | |
27 | //! ## When to use `*_unstable` | |
28 | //! | |
29 | //! Use this constructor if your data provider implements the [`DataProvider`] trait for all | |
30 | //! data structs in *current and future* ICU4X versions. Examples: | |
31 | //! | |
32 | //! 1. `BakedDataProvider` auto-regenerated on new ICU4X versions | |
33 | //! 2. Anything with a _blanket_ [`DataProvider`] impl | |
34 | //! | |
35 | //! Since the exact set of bounds may change at any time, including in minor SemVer releases, | |
36 | //! it is the client's responsibility to guarantee that the requirement is upheld. | |
37 | //! | |
38 | //! ## When to use `*_with_any_provider` | |
39 | //! | |
40 | //! Use this constructor if you need to use a provider that implements [`AnyProvider`] but not | |
41 | //! [`DataProvider`]. Examples: | |
42 | //! | |
43 | //! 1. [`AnyPayloadProvider`] | |
44 | //! 2. [`ForkByKeyProvider`] between two providers implementing [`AnyProvider`] | |
45 | //! 3. Providers that cache or override certain keys but not others and therefore | |
46 | //! can't implement [`DataProvider`] | |
47 | //! | |
48 | //! ## When to use `*_with_buffer_provider` | |
49 | //! | |
50 | //! Use this constructor if your data originates as byte buffers that need to be deserialized. | |
51 | //! All such providers should implement [`BufferProvider`]. Examples: | |
52 | //! | |
53 | //! 1. [`BlobDataProvider`] | |
54 | //! 2. [`FsDataProvider`] | |
55 | //! 3. [`ForkByKeyProvider`] between any of the above | |
56 | //! | |
9ffffee4 | 57 | //! Please note that you must enable the `"serde"` Cargo feature on each crate in which you use the |
487cf647 FG |
58 | //! `*_with_buffer_provider` constructor. |
59 | //! | |
60 | //! # Data Versioning Policy | |
61 | //! | |
62 | //! The `*_with_any_provider` and `*_with_buffer_provider` functions will succeed to compile and | |
63 | //! run if given a data provider supporting all of the keys required for the object being | |
64 | //! constructed, either the current or any previous version within the same SemVer major release. | |
65 | //! For example, if a data file is built to support FooFormatter version 1.1, then FooFormatter | |
66 | //! version 1.2 will be able to read the same data file. Likewise, backwards-compatible keys can | |
67 | //! always be included by `icu_datagen` to support older library versions. | |
68 | //! | |
69 | //! The `*_unstable` functions are only guaranteed to work on data built for the exact same version | |
70 | //! of ICU4X. The advantage of the `*_unstable` functions is that they result in the smallest code | |
71 | //! size and allow for automatic data slicing when `BakedDataProvider` is used. However, the type | |
72 | //! bounds of this function may change over time, breaking SemVer guarantees. These functions | |
73 | //! should therefore only be used when you have full control over your data lifecycle at compile | |
74 | //! time. | |
75 | //! | |
76 | //! # Data Providers Over FFI | |
77 | //! | |
78 | //! Over FFI, there is only one data provider type: [`ICU4XDataProvider`]. Internally, it is an | |
79 | //! `enum` between `dyn `[`AnyProvider`] and `dyn `[`BufferProvider`]. | |
80 | //! | |
9ffffee4 FG |
81 | //! To control for code size, there are two Cargo features, `any_provider` and `buffer_provider`, |
82 | //! that enable the corresponding items in the enum. | |
487cf647 FG |
83 | //! |
84 | //! In Rust ICU4X, a similar buffer/any enum approach was not taken because: | |
85 | //! | |
86 | //! 1. Feature-gating the enum branches gets complex across crates. | |
87 | //! 2. Without feature gating, users need to carry Serde code even if they're not using it, | |
88 | //! violating one of the core value propositions of ICU4X. | |
89 | //! 3. We could reduce the number of constructors from 3 to 2 but not to 1, so the educational | |
90 | //! benefit is limited. | |
91 | //! | |
92 | //! | |
93 | //! [`DataProvider`]: crate::DataProvider | |
94 | //! [`BufferProvider`]: crate::BufferProvider | |
95 | //! [`AnyProvider`]: crate::AnyProvider | |
96 | //! [`AnyPayloadProvider`]: ../../icu_provider_adapters/any_payload/struct.AnyPayloadProvider.html | |
97 | //! [`ForkByKeyProvider`]: ../../icu_provider_adapters/fork/struct.ForkByKeyProvider.html | |
98 | //! [`BlobDataProvider`]: ../../icu_provider_blob/struct.BlobDataProvider.html | |
99 | //! [`StaticDataProvider`]: ../../icu_provider_blob/struct.StaticDataProvider.html | |
100 | //! [`FsDataProvider`]: ../../icu_provider_blob/struct.FsDataProvider.html | |
101 | //! [`ICU4XDataProvider`]: ../../icu_capi/provider/ffi/struct.ICU4XDataProvider.html |