/rust/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.0.1/src/emoji.rs
Line | Count | Source |
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 | | use crate::provider::*; |
6 | | use icu_collections::codepointinvliststringlist::CodePointInversionListAndStringList; |
7 | | use icu_provider::marker::ErasedMarker; |
8 | | use icu_provider::prelude::*; |
9 | | |
10 | | /// A wrapper around `UnicodeSet` data (characters and strings) |
11 | | #[derive(Debug)] |
12 | | pub struct EmojiSetData { |
13 | | data: DataPayload<ErasedMarker<PropertyUnicodeSet<'static>>>, |
14 | | } |
15 | | |
16 | | impl EmojiSetData { |
17 | | /// Creates a new [`EmojiSetDataBorrowed`] for a [`EmojiSet`]. |
18 | | /// |
19 | | /// See the documentation on [`EmojiSet`] implementations for details. |
20 | | /// |
21 | | /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
22 | | /// |
23 | | /// [📚 Help choosing a constructor](icu_provider::constructors) |
24 | | #[cfg(feature = "compiled_data")] |
25 | | #[allow(clippy::new_ret_no_self)] |
26 | 0 | pub const fn new<P: EmojiSet>() -> EmojiSetDataBorrowed<'static> { |
27 | 0 | EmojiSetDataBorrowed::new::<P>() |
28 | 0 | } |
29 | | |
30 | | /// A version of `new()` that uses custom data provided by a [`DataProvider`]. |
31 | | /// |
32 | | /// Note that this will return an owned version of the data. Functionality is available on |
33 | | /// the borrowed version, accessible through [`EmojiSetData::as_borrowed`]. |
34 | 0 | pub fn try_new_unstable<P: EmojiSet>( |
35 | 0 | provider: &(impl DataProvider<P::DataMarker> + ?Sized), |
36 | 0 | ) -> Result<EmojiSetData, DataError> { |
37 | 0 | Ok(EmojiSetData::from_data( |
38 | 0 | provider.load(Default::default())?.payload, |
39 | | )) |
40 | 0 | } |
41 | | |
42 | | /// Construct a borrowed version of this type that can be queried. |
43 | | /// |
44 | | /// This avoids a potential small underlying cost per API call (ex: `contains()`) by consolidating it |
45 | | /// up front. |
46 | | #[inline] |
47 | 0 | pub fn as_borrowed(&self) -> EmojiSetDataBorrowed<'_> { |
48 | 0 | EmojiSetDataBorrowed { |
49 | 0 | set: self.data.get(), |
50 | 0 | } |
51 | 0 | } |
52 | | |
53 | | /// Construct a new one from loaded data |
54 | | /// |
55 | | /// Typically it is preferable to use getters instead |
56 | 0 | pub(crate) fn from_data<M>(data: DataPayload<M>) -> Self |
57 | 0 | where |
58 | 0 | M: DynamicDataMarker<DataStruct = PropertyUnicodeSet<'static>>, |
59 | | { |
60 | 0 | Self { data: data.cast() } |
61 | 0 | } |
62 | | |
63 | | /// Construct a new owned [`CodePointInversionListAndStringList`] |
64 | 0 | pub fn from_code_point_inversion_list_string_list( |
65 | 0 | set: CodePointInversionListAndStringList<'static>, |
66 | 0 | ) -> Self { |
67 | 0 | let set = PropertyUnicodeSet::from_code_point_inversion_list_string_list(set); |
68 | 0 | EmojiSetData::from_data( |
69 | 0 | DataPayload::<ErasedMarker<PropertyUnicodeSet<'static>>>::from_owned(set), |
70 | | ) |
71 | 0 | } |
72 | | |
73 | | /// Convert this type to a [`CodePointInversionListAndStringList`] as a borrowed value. |
74 | | /// |
75 | | /// The data backing this is extensible and supports multiple implementations. |
76 | | /// Currently it is always [`CodePointInversionListAndStringList`]; however in the future more backends may be |
77 | | /// added, and users may select which at data generation time. |
78 | | /// |
79 | | /// This method returns an `Option` in order to return `None` when the backing data provider |
80 | | /// cannot return a [`CodePointInversionListAndStringList`], or cannot do so within the expected constant time |
81 | | /// constraint. |
82 | 0 | pub fn as_code_point_inversion_list_string_list( |
83 | 0 | &self, |
84 | 0 | ) -> Option<&CodePointInversionListAndStringList<'_>> { |
85 | 0 | self.data.get().as_code_point_inversion_list_string_list() |
86 | 0 | } |
87 | | |
88 | | /// Convert this type to a [`CodePointInversionListAndStringList`], borrowing if possible, |
89 | | /// otherwise allocating a new [`CodePointInversionListAndStringList`]. |
90 | | /// |
91 | | /// The data backing this is extensible and supports multiple implementations. |
92 | | /// Currently it is always [`CodePointInversionListAndStringList`]; however in the future more backends may be |
93 | | /// added, and users may select which at data generation time. |
94 | | /// |
95 | | /// The performance of the conversion to this specific return type will vary |
96 | | /// depending on the data structure that is backing `self`. |
97 | 0 | pub fn to_code_point_inversion_list_string_list( |
98 | 0 | &self, |
99 | 0 | ) -> CodePointInversionListAndStringList<'_> { |
100 | 0 | self.data.get().to_code_point_inversion_list_string_list() |
101 | 0 | } |
102 | | } |
103 | | |
104 | | /// A borrowed wrapper around code point set data, returned by |
105 | | /// [`EmojiSetData::as_borrowed()`]. More efficient to query. |
106 | | #[derive(Clone, Copy, Debug)] |
107 | | pub struct EmojiSetDataBorrowed<'a> { |
108 | | set: &'a PropertyUnicodeSet<'a>, |
109 | | } |
110 | | |
111 | | impl EmojiSetDataBorrowed<'_> { |
112 | | /// Check if the set contains the string. Strings consisting of one character |
113 | | /// are treated as a character/code point. |
114 | | /// |
115 | | /// This matches ICU behavior for ICU's `UnicodeSet`. |
116 | | #[inline] |
117 | 0 | pub fn contains_str(self, s: &str) -> bool { |
118 | 0 | self.set.contains_str(s) |
119 | 0 | } |
120 | | |
121 | | /// Check if the set contains the code point. |
122 | | #[inline] |
123 | 0 | pub fn contains(self, ch: char) -> bool { |
124 | 0 | self.set.contains(ch) |
125 | 0 | } |
126 | | |
127 | | /// See [`Self::contains`]. |
128 | | #[inline] |
129 | 0 | pub fn contains32(self, cp: u32) -> bool { |
130 | 0 | self.set.contains32(cp) |
131 | 0 | } |
132 | | } |
133 | | |
134 | | impl EmojiSetDataBorrowed<'static> { |
135 | | /// Creates a new [`EmojiSetDataBorrowed`] for a [`EmojiSet`]. |
136 | | /// |
137 | | /// See the documentation on [`EmojiSet`] implementations for details. |
138 | | /// |
139 | | /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
140 | | /// |
141 | | /// [📚 Help choosing a constructor](icu_provider::constructors) |
142 | | #[inline] |
143 | | #[cfg(feature = "compiled_data")] |
144 | 0 | pub const fn new<P: EmojiSet>() -> Self { |
145 | 0 | EmojiSetDataBorrowed { set: P::SINGLETON } |
146 | 0 | } |
147 | | |
148 | | /// Cheaply converts a [`EmojiSetDataBorrowed<'static>`] into a [`EmojiSetData`]. |
149 | | /// |
150 | | /// Note: Due to branching and indirection, using [`EmojiSetData`] might inhibit some |
151 | | /// compile-time optimizations that are possible with [`EmojiSetDataBorrowed`]. |
152 | 0 | pub const fn static_to_owned(self) -> EmojiSetData { |
153 | 0 | EmojiSetData { |
154 | 0 | data: DataPayload::from_static_ref(self.set), |
155 | 0 | } |
156 | 0 | } |
157 | | } |
158 | | |
159 | | /// An Emoji set as defined by [`Unicode Technical Standard #51`](https://unicode.org/reports/tr51/#Emoji_Sets>). |
160 | | /// |
161 | | /// <div class="stab unstable"> |
162 | | /// 🚫 This trait is sealed; it cannot be implemented by user code. If an API requests an item that implements this |
163 | | /// trait, please consider using a type from the implementors listed below. |
164 | | /// </div> |
165 | | pub trait EmojiSet: crate::private::Sealed { |
166 | | #[doc(hidden)] |
167 | | type DataMarker: DataMarker<DataStruct = PropertyUnicodeSet<'static>>; |
168 | | #[doc(hidden)] |
169 | | #[cfg(feature = "compiled_data")] |
170 | | const SINGLETON: &'static PropertyUnicodeSet<'static>; |
171 | | } |