Coverage Report

Created: 2025-09-27 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}