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 ).
45use crate::provider::*;
6use icu_collections::codepointinvliststringlist::CodePointInversionListAndStringList;
7use icu_provider::marker::ErasedMarker;
8use icu_provider::prelude::*;
910/// A wrapper around `UnicodeSet` data (characters and strings)
11#[derive(#[automatically_derived]
impl ::core::fmt::Debug for EmojiSetData {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f, "EmojiSetData",
"data", &&self.data)
}
}Debug)]
12pub struct EmojiSetData {
13 data: DataPayload<ErasedMarker<PropertyUnicodeSet<'static>>>,
14}
1516impl 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 #[expect(clippy::new_ret_no_self)]
26pub const fn new<P: EmojiSet>() -> EmojiSetDataBorrowed<'static> {
27EmojiSetDataBorrowed::new::<P>()
28 }
2930/// 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`].
34pub fn try_new_unstable<P: EmojiSet>(
35 provider: &(impl DataProvider<P::DataMarker> + ?Sized),
36 ) -> Result<EmojiSetData, DataError> {
37Ok(EmojiSetData::from_data(
38provider.load(Default::default())?.payload,
39 ))
40 }
4142/// 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]
47pub fn as_borrowed(&self) -> EmojiSetDataBorrowed<'_> {
48EmojiSetDataBorrowed {
49 set: self.data.get(),
50 }
51 }
5253/// Construct a new one from loaded data
54 ///
55 /// Typically it is preferable to use getters instead
56pub(crate) fn from_data<M>(data: DataPayload<M>) -> Self
57where
58M: DynamicDataMarker<DataStruct = PropertyUnicodeSet<'static>>,
59 {
60Self { data: data.cast() }
61 }
6263/// Construct a new owned [`CodePointInversionListAndStringList`]
64pub fn from_code_point_inversion_list_string_list(
65 set: CodePointInversionListAndStringList<'static>,
66 ) -> Self {
67let set = PropertyUnicodeSet::from_code_point_inversion_list_string_list(set);
68EmojiSetData::from_data(
69DataPayload::<ErasedMarker<PropertyUnicodeSet<'static>>>::from_owned(set),
70 )
71 }
7273/// 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.
82pub fn as_code_point_inversion_list_string_list(
83&self,
84 ) -> Option<&CodePointInversionListAndStringList<'_>> {
85self.data.get().as_code_point_inversion_list_string_list()
86 }
8788/// 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`.
97pub fn to_code_point_inversion_list_string_list(
98&self,
99 ) -> CodePointInversionListAndStringList<'_> {
100self.data.get().to_code_point_inversion_list_string_list()
101 }
102}
103104/// A borrowed wrapper around code point set data, returned by
105/// [`EmojiSetData::as_borrowed()`]. More efficient to query.
106#[derive(#[automatically_derived]
impl<'a> ::core::clone::Clone for EmojiSetDataBorrowed<'a> {
#[inline]
fn clone(&self) -> EmojiSetDataBorrowed<'a> {
let _: ::core::clone::AssertParamIsClone<&'a PropertyUnicodeSet<'a>>;
*self
}
}Clone, #[automatically_derived]
impl<'a> ::core::marker::Copy for EmojiSetDataBorrowed<'a> { }Copy, #[automatically_derived]
impl<'a> ::core::fmt::Debug for EmojiSetDataBorrowed<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"EmojiSetDataBorrowed", "set", &&self.set)
}
}Debug)]
107pub struct EmojiSetDataBorrowed<'a> {
108 set: &'a PropertyUnicodeSet<'a>,
109}
110111impl 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]
117pub fn contains_str(self, s: &str) -> bool {
118self.set.contains_str(s)
119 }
120121/// Check if the set contains the code point.
122#[inline]
123pub fn contains(self, ch: char) -> bool {
124self.set.contains(ch)
125 }
126127/// See [`Self::contains`].
128#[inline]
129pub fn contains32(self, cp: u32) -> bool {
130self.set.contains32(cp)
131 }
132}
133134impl 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")]
144pub const fn new<P: EmojiSet>() -> Self {
145EmojiSetDataBorrowed { set: P::SINGLETON }
146 }
147148/// 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`].
152pub const fn static_to_owned(self) -> EmojiSetData {
153EmojiSetData {
154 data: DataPayload::from_static_ref(self.set),
155 }
156 }
157}
158159/// 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>
165pub trait EmojiSet: crate::private::Sealed {
166#[doc(hidden)]
167type DataMarker: DataMarker<DataStruct = PropertyUnicodeSet<'static>>;
168#[doc(hidden)]
169 #[cfg(feature = "compiled_data")]
170const SINGLETON: &'static PropertyUnicodeSet<'static>;
171}