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
7use crate::key::DataKey;
8use 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
58pub 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
83pub trait KeyedDataMarker: DataMarker {
84 /// The single [`DataKey`] associated with this marker.
85 const KEY: DataKey;
86}
87