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 | //! Marker types and traits for DataProvider. |
6 | |
7 | use crate::key::DataKey; |
8 | use yoke::Yokeable; |
9 | |
10 | /// Trait marker for data structs. All types delivered by the data provider must be associated with |
11 | /// something implementing this trait. |
12 | /// |
13 | /// Structs implementing this trait are normally generated with the [`data_struct`] macro. |
14 | /// |
15 | /// By convention, the non-standard `Marker` suffix is used by types implementing DataMarker. |
16 | /// |
17 | /// In addition to a marker type implementing DataMarker, the following impls must also be present |
18 | /// for the data struct: |
19 | /// |
20 | /// - `impl<'a> Yokeable<'a>` (required) |
21 | /// - `impl ZeroFrom<Self>` |
22 | /// |
23 | /// Also see [`KeyedDataMarker`]. |
24 | /// |
25 | /// Note: `DataMarker`s are quasi-const-generic compile-time objects, and as such are expected |
26 | /// to be unit structs. As this is not something that can be enforced by the type system, we |
27 | /// currently only have a `'static` bound on them (which is needed by a lot of our code). |
28 | /// |
29 | /// # Examples |
30 | /// |
31 | /// Manually implementing DataMarker for a custom type: |
32 | /// |
33 | /// ``` |
34 | /// use icu_provider::prelude::*; |
35 | /// use std::borrow::Cow; |
36 | /// use std::rc::Rc; |
37 | /// |
38 | /// #[derive(yoke::Yokeable, zerofrom::ZeroFrom)] |
39 | /// struct MyDataStruct<'data> { |
40 | /// message: Cow<'data, str>, |
41 | /// } |
42 | /// |
43 | /// struct MyDataStructMarker; |
44 | /// |
45 | /// impl DataMarker for MyDataStructMarker { |
46 | /// type Yokeable = MyDataStruct<'static>; |
47 | /// } |
48 | /// |
49 | /// // We can now use MyDataStruct with DataProvider: |
50 | /// let s = MyDataStruct { |
51 | /// message: Cow::Owned("Hello World" .into()), |
52 | /// }; |
53 | /// let payload = DataPayload::<MyDataStructMarker>::from_owned(s); |
54 | /// assert_eq!(payload.get().message, "Hello World" ); |
55 | /// ``` |
56 | /// |
57 | /// [`data_struct`]: crate::data_struct |
58 | pub trait DataMarker: 'static { |
59 | /// A type that implements [`Yokeable`]. This should typically be the `'static` version of a |
60 | /// data struct. |
61 | type Yokeable: for<'a> Yokeable<'a>; |
62 | } |
63 | |
64 | /// A [`DataMarker`] with a [`DataKey`] attached. |
65 | /// |
66 | /// Structs implementing this trait are normally generated with the [`data_struct!`] macro. |
67 | /// |
68 | /// Implementing this trait enables this marker to be used with the main [`DataProvider`] trait. |
69 | /// Most markers should be associated with a specific key and should therefore implement this |
70 | /// trait. |
71 | /// |
72 | /// [`BufferMarker`] and [`AnyMarker`] are examples of markers that do _not_ implement this trait |
73 | /// because they are not specific to a single key. |
74 | /// |
75 | /// Note: `KeyedDataMarker`s are quasi-const-generic compile-time objects, and as such are expected |
76 | /// to be unit structs. As this is not something that can be enforced by the type system, we |
77 | /// currently only have a `'static` bound on them (which is needed by a lot of our code). |
78 | /// |
79 | /// [`data_struct!`]: crate::data_struct |
80 | /// [`DataProvider`]: crate::DataProvider |
81 | /// [`BufferMarker`]: crate::BufferMarker |
82 | /// [`AnyMarker`]: crate::AnyMarker |
83 | pub trait KeyedDataMarker: DataMarker { |
84 | /// The single [`DataKey`] associated with this marker. |
85 | const KEY: DataKey; |
86 | } |
87 | |