/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  |  | }  |