@@ -6,33 +6,37 @@ use super::*;
6
6
use alloc:: boxed:: Box ;
7
7
use icu_provider:: prelude:: * ;
8
8
9
- use icu_locale:: LanguageIdentifier ;
10
-
11
- type RequestFilterDataProviderOutput < ' a , D > =
12
- RequestFilterDataProvider < D , Box < dyn Fn ( DataRequest ) -> bool + Sync + ' a > > ;
9
+ impl < D > FilterDataProvider < D , fn ( DataIdentifierBorrowed ) -> bool > {
10
+ /// Creates a [`FilterDataProvider`] that does not do any filtering.
11
+ ///
12
+ /// Filters can be added using [`Self::with_filter`].
13
+ pub fn new ( provider : D , filter_name : & ' static str ) -> Self {
14
+ Self {
15
+ inner : provider,
16
+ predicate : |_| true ,
17
+ filter_name,
18
+ }
19
+ }
20
+ }
13
21
14
- impl < D , F > RequestFilterDataProvider < D , F >
22
+ impl < D , F > FilterDataProvider < D , F >
15
23
where
16
- F : Fn ( DataRequest ) -> bool + Sync ,
24
+ F : Fn ( DataIdentifierBorrowed ) -> bool + Sync ,
17
25
{
18
26
/// Filter out data requests with certain langids according to the predicate function. The
19
27
/// predicate should return `true` to allow a langid and `false` to reject a langid.
20
28
///
21
- /// Data requests with no langid will be allowed. To reject data requests without a langid,
22
- /// chain this with [`Self::require_langid`].
23
- ///
24
29
/// # Examples
25
30
///
26
31
/// ```
27
32
/// use icu_locale::LanguageIdentifier;
28
33
/// use icu_locale::{langid, subtags::language};
29
34
/// use icu_provider::hello_world::*;
30
35
/// use icu_provider::prelude::*;
31
- /// use icu_provider_adapters::filter::Filterable ;
36
+ /// use icu_provider_adapters::filter::FilterDataProvider ;
32
37
///
33
- /// let provider = HelloWorldProvider
34
- /// .filterable("Demo no-English filter")
35
- /// .filter_by_langid(|langid| langid.language != language!("en"));
38
+ /// let provider = FilterDataProvider::new(HelloWorldProvider, "Demo no-English filter")
39
+ /// .with_filter(|id| id.locale.language() != language!("en"));
36
40
///
37
41
/// // German requests should succeed:
38
42
/// let de = DataIdentifierCow::from_locale(langid!("de").into());
58
62
/// assert!(matches!(
59
63
/// response,
60
64
/// Err(DataError {
61
- /// kind: DataErrorKind::Filtered ,
65
+ /// kind: DataErrorKind::IdentifierNotFound ,
62
66
/// ..
63
67
/// })
64
68
/// ));
@@ -70,147 +74,22 @@ where
70
74
/// assert!(available_ids.contains(&DataIdentifierCow::from_locale(langid!("de").into())));
71
75
/// assert!(!available_ids.contains(&DataIdentifierCow::from_locale(langid!("en").into())));
72
76
/// ```
73
- pub fn filter_by_langid < ' a > (
77
+ #[ allow( clippy:: type_complexity) ]
78
+ pub fn with_filter < ' a > (
74
79
self ,
75
- predicate : impl Fn ( & LanguageIdentifier ) -> bool + Sync + ' a ,
76
- ) -> RequestFilterDataProviderOutput < ' a , D >
77
- where
78
- F : ' a ,
79
- {
80
- let old_predicate = self . predicate ;
81
- RequestFilterDataProvider {
82
- inner : self . inner ,
83
- predicate : Box :: new ( move |request| -> bool {
84
- if !( old_predicate) ( request) {
85
- return false ;
86
- }
87
- predicate ( & request. id . locale . get_langid ( ) )
88
- } ) ,
89
- filter_name : self . filter_name ,
90
- }
91
- }
92
-
93
- /// Filter out data request except those having a language identifier that exactly matches
94
- /// one in the allowlist.
95
- ///
96
- /// This will be replaced with a smarter algorithm for locale filtering; see
97
- /// <https://github.com/unicode-org/icu4x/issues/834>
98
- ///
99
- /// Data requests with no langid will be allowed. To reject data requests without a langid,
100
- /// chain this with [`Self::require_langid`].
101
- ///
102
- /// # Examples
103
- ///
104
- /// ```
105
- /// use icu_locale::langid;
106
- /// use icu_provider::hello_world::*;
107
- /// use icu_provider::prelude::*;
108
- /// use icu_provider_adapters::filter::Filterable;
109
- ///
110
- /// let allowlist = [langid!("de"), langid!("zh")];
111
- /// let provider = HelloWorldProvider
112
- /// .filterable("Demo German+Chinese filter")
113
- /// .filter_by_langid_allowlist_strict(&allowlist);
114
- ///
115
- /// // German requests should succeed:
116
- /// let de = DataIdentifierCow::from_locale(langid!("de").into());
117
- /// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
118
- /// provider.load(DataRequest {
119
- /// id: de.as_borrowed(),
120
- /// ..Default::default()
121
- /// });
122
- /// assert!(matches!(response, Ok(_)));
123
- ///
124
- /// // English requests should fail:
125
- /// let en = DataIdentifierCow::from_locale(langid!("en-US").into());
126
-
127
- /// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
128
- /// provider.load(DataRequest {
129
- /// id: en.as_borrowed(),
130
- /// ..Default::default()
131
- /// });
132
- /// assert!(matches!(
133
- /// response,
134
- /// Err(DataError {
135
- /// kind: DataErrorKind::Filtered,
136
- /// ..
137
- /// })
138
- /// ));
139
- /// assert_eq!(
140
- /// response.unwrap_err().str_context,
141
- /// Some("Demo German+Chinese filter")
142
- /// );
143
- /// ```
144
- pub fn filter_by_langid_allowlist_strict < ' a > (
145
- self ,
146
- allowlist : & ' a [ LanguageIdentifier ] ,
147
- ) -> RequestFilterDataProviderOutput < ' a , D >
148
- where
149
- F : ' a ,
150
- {
151
- let old_predicate = self . predicate ;
152
- RequestFilterDataProvider {
153
- inner : self . inner ,
154
- predicate : Box :: new ( move |request| -> bool {
155
- if !( old_predicate) ( request) {
156
- return false ;
157
- }
158
- request. id . locale . is_langid_und ( )
159
- || allowlist. contains ( & request. id . locale . get_langid ( ) )
160
- } ) ,
161
- filter_name : self . filter_name ,
162
- }
163
- }
164
-
165
- /// Require that data requests contain a langid.
166
- ///
167
- /// # Examples
168
- ///
169
- /// ```
170
- /// use icu_locale::langid;
171
- /// use icu_provider::hello_world::*;
172
- /// use icu_provider::prelude::*;
173
- /// use icu_provider_adapters::filter::Filterable;
174
- ///
175
- /// let provider = HelloWorldProvider
176
- /// .filterable("Demo require-langid filter")
177
- /// .require_langid();
178
- ///
179
- /// // Requests with a data id should succeed:
180
- /// let id = DataIdentifierCow::from_locale(langid!("de").into());
181
- /// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
182
- /// provider.load(DataRequest {
183
- /// id: id.as_borrowed(),
184
- /// ..Default::default()
185
- /// });
186
- /// assert!(matches!(response, Ok(_)));
187
- ///
188
- /// // Requests without a data should fail:
189
- /// let response: Result<DataResponse<HelloWorldV1Marker>, _> =
190
- /// provider.load(DataRequest {
191
- /// id: Default::default(),
192
- /// ..Default::default()
193
- /// });
194
- /// assert!(matches!(
195
- /// response,
196
- /// Err(DataError {
197
- /// kind: DataErrorKind::Filtered,
198
- /// ..
199
- /// })
200
- /// ));
201
- /// ```
202
- pub fn require_langid < ' a > ( self ) -> RequestFilterDataProviderOutput < ' a , D >
80
+ predicate : impl Fn ( DataIdentifierBorrowed ) -> bool + Sync + ' a ,
81
+ ) -> FilterDataProvider < D , Box < dyn Fn ( DataIdentifierBorrowed ) -> bool + Sync + ' a > >
203
82
where
204
83
F : ' a ,
205
84
{
206
85
let old_predicate = self . predicate ;
207
- RequestFilterDataProvider {
86
+ FilterDataProvider {
208
87
inner : self . inner ,
209
- predicate : Box :: new ( move |request | -> bool {
210
- if !( old_predicate) ( request ) {
88
+ predicate : Box :: new ( move |id | -> bool {
89
+ if !( old_predicate) ( id ) {
211
90
return false ;
212
91
}
213
- !request . id . locale . is_langid_und ( )
92
+ predicate ( id )
214
93
} ) ,
215
94
filter_name : self . filter_name ,
216
95
}
0 commit comments