/rust/registry/src/index.crates.io-1949cf8c6b5b557f/icu_casemap-1.5.1/src/closer.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::{CaseMapUnfoldV1Marker, CaseMapV1Marker}; |
6 | | use crate::set::ClosureSink; |
7 | | use crate::CaseMapper; |
8 | | |
9 | | use icu_provider::prelude::*; |
10 | | |
11 | | /// A wrapper around [`CaseMapper`] that can produce case mapping closures |
12 | | /// over a character or string. This wrapper can be constructed directly, or |
13 | | /// by wrapping a reference to an existing [`CaseMapper`]. |
14 | | /// |
15 | | /// # Examples |
16 | | /// |
17 | | /// ```rust |
18 | | /// use icu::casemap::CaseMapCloser; |
19 | | /// use icu::collections::codepointinvlist::CodePointInversionListBuilder; |
20 | | /// |
21 | | /// let cm = CaseMapCloser::new(); |
22 | | /// let mut builder = CodePointInversionListBuilder::new(); |
23 | | /// let found = cm.add_string_case_closure_to("ffi", &mut builder); |
24 | | /// assert!(found); |
25 | | /// let set = builder.build(); |
26 | | /// |
27 | | /// assert!(set.contains('ffi')); |
28 | | /// |
29 | | /// let mut builder = CodePointInversionListBuilder::new(); |
30 | | /// let found = cm.add_string_case_closure_to("ss", &mut builder); |
31 | | /// assert!(found); |
32 | | /// let set = builder.build(); |
33 | | /// |
34 | | /// assert!(set.contains('ß')); |
35 | | /// assert!(set.contains('ẞ')); |
36 | | /// ``` |
37 | | #[derive(Clone, Debug)] |
38 | | pub struct CaseMapCloser<CM> { |
39 | | cm: CM, |
40 | | unfold: DataPayload<CaseMapUnfoldV1Marker>, |
41 | | } |
42 | | |
43 | | #[cfg(feature = "compiled_data")] |
44 | | impl Default for CaseMapCloser<CaseMapper> { |
45 | | /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
46 | 0 | fn default() -> Self { |
47 | 0 | Self::new() |
48 | 0 | } |
49 | | } |
50 | | |
51 | | impl CaseMapCloser<CaseMapper> { |
52 | | /// A constructor which creates a [`CaseMapCloser`] using compiled data. |
53 | | /// |
54 | | /// # Examples |
55 | | /// |
56 | | /// ```rust |
57 | | /// use icu::casemap::CaseMapCloser; |
58 | | /// use icu::collections::codepointinvlist::CodePointInversionListBuilder; |
59 | | /// |
60 | | /// let cm = CaseMapCloser::new(); |
61 | | /// let mut builder = CodePointInversionListBuilder::new(); |
62 | | /// let found = cm.add_string_case_closure_to("ffi", &mut builder); |
63 | | /// assert!(found); |
64 | | /// let set = builder.build(); |
65 | | /// |
66 | | /// assert!(set.contains('ffi')); |
67 | | /// |
68 | | /// let mut builder = CodePointInversionListBuilder::new(); |
69 | | /// let found = cm.add_string_case_closure_to("ss", &mut builder); |
70 | | /// assert!(found); |
71 | | /// let set = builder.build(); |
72 | | /// |
73 | | /// assert!(set.contains('ß')); |
74 | | /// assert!(set.contains('ẞ')); |
75 | | /// ``` |
76 | | /// |
77 | | /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
78 | | /// |
79 | | /// [📚 Help choosing a constructor](icu_provider::constructors) |
80 | | #[cfg(feature = "compiled_data")] |
81 | 0 | pub const fn new() -> Self { |
82 | 0 | Self { |
83 | 0 | cm: CaseMapper::new(), |
84 | 0 | unfold: DataPayload::from_static_ref( |
85 | 0 | crate::provider::Baked::SINGLETON_PROPS_CASEMAP_UNFOLD_V1, |
86 | 0 | ), |
87 | 0 | } |
88 | 0 | } |
89 | | |
90 | | icu_provider::gen_any_buffer_data_constructors!(locale: skip, options: skip, error: DataError, |
91 | | #[cfg(skip)] |
92 | | functions: [ |
93 | | new, |
94 | | try_new_with_any_provider, |
95 | | try_new_with_buffer_provider, |
96 | | try_new_unstable, |
97 | | Self, |
98 | | ]); |
99 | | |
100 | | #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new)] |
101 | 0 | pub fn try_new_unstable<P>(provider: &P) -> Result<Self, DataError> |
102 | 0 | where |
103 | 0 | P: DataProvider<CaseMapV1Marker> + DataProvider<CaseMapUnfoldV1Marker> + ?Sized, |
104 | | { |
105 | 0 | let cm = CaseMapper::try_new_unstable(provider)?; |
106 | 0 | let unfold = provider.load(Default::default())?.take_payload()?; |
107 | 0 | Ok(Self { cm, unfold }) |
108 | 0 | } Unexecuted instantiation: <icu_casemap::closer::CaseMapCloser<icu_casemap::casemapper::CaseMapper>>::try_new_unstable::<icu_provider::any::DowncastingAnyProvider<icu_provider_adapters::empty::EmptyDataProvider>> Unexecuted instantiation: <icu_casemap::closer::CaseMapCloser<icu_casemap::casemapper::CaseMapper>>::try_new_unstable::<_> |
109 | | } |
110 | | |
111 | | // We use Borrow, not AsRef, since we want the blanket impl on T |
112 | | impl<CM: AsRef<CaseMapper>> CaseMapCloser<CM> { |
113 | | icu_provider::gen_any_buffer_data_constructors!(locale: skip, casemapper: CM, error: DataError, |
114 | | #[cfg(skip)] |
115 | | functions: [ |
116 | | new_with_mapper, |
117 | | try_new_with_mapper_with_any_provider, |
118 | | try_new_with_mapper_with_buffer_provider, |
119 | | try_new_with_mapper_unstable, |
120 | | Self, |
121 | | ]); |
122 | | |
123 | | /// A constructor which creates a [`CaseMapCloser`] from an existing [`CaseMapper`] |
124 | | /// (either owned or as a reference) |
125 | | /// |
126 | | /// ✨ *Enabled with the `compiled_data` Cargo feature.* |
127 | | /// |
128 | | /// [📚 Help choosing a constructor](icu_provider::constructors) |
129 | | #[cfg(feature = "compiled_data")] |
130 | 0 | pub const fn new_with_mapper(casemapper: CM) -> Self { |
131 | 0 | Self { |
132 | 0 | cm: casemapper, |
133 | 0 | unfold: DataPayload::from_static_ref( |
134 | 0 | crate::provider::Baked::SINGLETON_PROPS_CASEMAP_UNFOLD_V1, |
135 | 0 | ), |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | | /// Construct this object to wrap an existing CaseMapper (or a reference to one), loading additional data as needed. |
140 | | #[doc = icu_provider::gen_any_buffer_unstable_docs!(UNSTABLE, Self::new_with_mapper)] |
141 | 0 | pub fn try_new_with_mapper_unstable<P>(provider: &P, casemapper: CM) -> Result<Self, DataError> |
142 | 0 | where |
143 | 0 | P: DataProvider<CaseMapV1Marker> + DataProvider<CaseMapUnfoldV1Marker> + ?Sized, |
144 | | { |
145 | 0 | let unfold = provider.load(Default::default())?.take_payload()?; |
146 | 0 | Ok(Self { |
147 | 0 | cm: casemapper, |
148 | 0 | unfold, |
149 | 0 | }) |
150 | 0 | } |
151 | | |
152 | | /// Adds all simple case mappings and the full case folding for `c` to `set`. |
153 | | /// Also adds special case closure mappings. |
154 | | /// |
155 | | /// In other words, this adds all strings/characters that this casemaps to, as |
156 | | /// well as all characters that may casemap to this one. |
157 | | /// |
158 | | /// The character itself is not added. |
159 | | /// |
160 | | /// For example, the mappings |
161 | | /// - for s include long s |
162 | | /// - for sharp s include ss |
163 | | /// - for k include the Kelvin sign |
164 | | /// |
165 | | /// This function is identical to [`CaseMapper::add_case_closure_to()`]; if you don't |
166 | | /// need [`Self::add_string_case_closure_to()`] consider using a [`CaseMapper`] to avoid |
167 | | /// loading additional data. |
168 | | /// |
169 | | /// # Examples |
170 | | /// |
171 | | /// ```rust |
172 | | /// use icu::casemap::CaseMapCloser; |
173 | | /// use icu::collections::codepointinvlist::CodePointInversionListBuilder; |
174 | | /// |
175 | | /// let cm = CaseMapCloser::new(); |
176 | | /// let mut builder = CodePointInversionListBuilder::new(); |
177 | | /// cm.add_case_closure_to('s', &mut builder); |
178 | | /// |
179 | | /// let set = builder.build(); |
180 | | /// |
181 | | /// assert!(set.contains('S')); |
182 | | /// assert!(set.contains('ſ')); |
183 | | /// assert!(!set.contains('s')); // does not contain itself |
184 | | /// ``` |
185 | 0 | pub fn add_case_closure_to<S: ClosureSink>(&self, c: char, set: &mut S) { |
186 | 0 | self.cm.as_ref().add_case_closure_to(c, set); |
187 | 0 | } Unexecuted instantiation: <icu_casemap::closer::CaseMapCloser<icu_casemap::casemapper::CaseMapper>>::add_case_closure_to::<icu_collections::codepointinvlist::builder::CodePointInversionListBuilder> Unexecuted instantiation: <icu_casemap::closer::CaseMapCloser<_>>::add_case_closure_to::<_> |
188 | | |
189 | | /// Finds all characters and strings which may casemap to `s` as their full case folding string |
190 | | /// and adds them to the set. Includes the full case closure of each character mapping. |
191 | | /// |
192 | | /// In other words, this performs a reverse full case folding and then |
193 | | /// adds the case closure items of the resulting code points. |
194 | | /// |
195 | | /// The string itself is not added to the set. |
196 | | /// |
197 | | /// Returns true if the string was found |
198 | | /// |
199 | | /// # Examples |
200 | | /// |
201 | | /// ```rust |
202 | | /// use icu::casemap::CaseMapCloser; |
203 | | /// use icu::collections::codepointinvlist::CodePointInversionListBuilder; |
204 | | /// |
205 | | /// let cm = CaseMapCloser::new(); |
206 | | /// let mut builder = CodePointInversionListBuilder::new(); |
207 | | /// let found = cm.add_string_case_closure_to("ffi", &mut builder); |
208 | | /// assert!(found); |
209 | | /// let set = builder.build(); |
210 | | /// |
211 | | /// assert!(set.contains('ffi')); |
212 | | /// |
213 | | /// let mut builder = CodePointInversionListBuilder::new(); |
214 | | /// let found = cm.add_string_case_closure_to("ss", &mut builder); |
215 | | /// assert!(found); |
216 | | /// let set = builder.build(); |
217 | | /// |
218 | | /// assert!(set.contains('ß')); |
219 | | /// assert!(set.contains('ẞ')); |
220 | | /// ``` |
221 | 0 | pub fn add_string_case_closure_to<S: ClosureSink>(&self, s: &str, set: &mut S) -> bool { |
222 | 0 | self.cm |
223 | 0 | .as_ref() |
224 | 0 | .data |
225 | 0 | .get() |
226 | 0 | .add_string_case_closure_to(s, set, self.unfold.get()) |
227 | 0 | } Unexecuted instantiation: <icu_casemap::closer::CaseMapCloser<icu_casemap::casemapper::CaseMapper>>::add_string_case_closure_to::<icu_collections::codepointinvlist::builder::CodePointInversionListBuilder> Unexecuted instantiation: <icu_casemap::closer::CaseMapCloser<_>>::add_string_case_closure_to::<_> |
228 | | } |