1
1
use general_filters:: { FunctionInImpl , FunctionInLines , FunctionWithParameterRust } ;
2
- use std:: { collections:: HashMap , fmt, hash:: Hash } ;
2
+ use std:: {
3
+ collections:: { hash_map, HashMap } ,
4
+ fmt,
5
+ hash:: Hash ,
6
+ } ;
3
7
4
8
mod filter_parsers;
5
9
mod general_filters;
@@ -36,15 +40,9 @@ use crate::SupportedLanguages;
36
40
pub trait Filter : HasFilterInformation {
37
41
fn parse_filter ( & self , s : & str ) -> Result < FilterFunction , String > ;
38
42
// TODO: make way to parse from hashmap of attribute to string
39
- fn to_filter ( & self , s : & str ) -> Result < InstantiatedFilter , String > {
43
+ fn to_filter ( & self , s : & str ) -> Result < InstantiatedFilter < Self :: Supports > , String > {
40
44
let filter = self . parse_filter ( s) ?;
41
45
let info = self . filter_info ( ) ;
42
- let info = FilterInformation {
43
- supported_languages : info. supported_languages . into ( ) ,
44
- description : info. description ,
45
- attributes : info. attributes ,
46
- filter_name : info. filter_name ,
47
- } ;
48
46
Ok ( InstantiatedFilter {
49
47
filter_information : info,
50
48
filter_function : filter,
@@ -130,32 +128,37 @@ type FilterFunction = Box<dyn Fn(&Node<'_>) -> bool + Send + Sync>;
130
128
// TODO: make our own FromStr that also requires the proggramer to sepcify that attributes each
131
129
// filter has and their type so that we can make macro that creates parser, and also so that we can
132
130
// communicate to a gui (or tui) that labels, and types of each input
133
- pub struct InstantiatedFilter {
134
- filter_information : FilterInformation < SupportedLanguages > ,
131
+ // TODO: make something that builds on this like FilterType
132
+ pub struct InstantiatedFilter < Supports > {
133
+ filter_information : FilterInformation < Supports > ,
135
134
filter_function : FilterFunction ,
136
135
}
137
136
138
- impl PartialEq for InstantiatedFilter {
137
+ impl < Supports : PartialEq > PartialEq for InstantiatedFilter < Supports > {
139
138
fn eq ( & self , other : & Self ) -> bool {
140
139
self . filter_information == other. filter_information
141
140
}
141
+
142
+ fn ne ( & self , other : & Self ) -> bool {
143
+ !self . eq ( other)
144
+ }
142
145
}
143
- impl Eq for InstantiatedFilter { }
146
+ impl < Supports : PartialEq > Eq for InstantiatedFilter < Supports > { }
144
147
145
- impl fmt:: Display for InstantiatedFilter {
148
+ impl < Supports > fmt:: Display for InstantiatedFilter < Supports > {
146
149
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
147
150
write ! ( f, "{}" , self . filter_information)
148
151
}
149
152
}
150
- impl std:: fmt:: Debug for InstantiatedFilter {
153
+ impl < Supports : std:: fmt:: Debug > std :: fmt :: Debug for InstantiatedFilter < Supports > {
151
154
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
152
155
f. debug_struct ( "InstantiatedFilter" )
153
156
. field ( "filter_information" , & self . filter_information )
154
157
. finish ( )
155
158
}
156
159
}
157
160
158
- impl InstantiatedFilter {
161
+ impl < Supports > InstantiatedFilter < Supports > {
159
162
#[ must_use]
160
163
pub fn filter ( & self , node : & Node < ' _ > ) -> bool {
161
164
( self . filter_function ) ( node)
@@ -177,7 +180,7 @@ impl InstantiatedFilter {
177
180
}
178
181
179
182
#[ must_use]
180
- pub const fn supported_languages ( & self ) -> & SupportedLanguages {
183
+ pub const fn supported_languages ( & self ) -> & Supports {
181
184
self . filter_information . supported_languages ( )
182
185
}
183
186
}
@@ -196,46 +199,95 @@ impl From<Language> for SupportedLanguages {
196
199
}
197
200
}
198
201
// impl Language for
202
+ // TODO: rework macro to work with the new language per filter system
199
203
macro_rules! default_filters {
200
204
( $( $filter: ident) ,* ) => { S
201
205
HashMap :: from( [ $( ( $filter. filter_info( ) . filter_name( ) . to_string( ) , & $filter as & ' static dyn Filter ) ) ,* ] )
202
206
} ;
203
207
}
204
- pub struct Many < ' a > {
208
+ pub struct Many < T : Info < Supported = Language > > {
205
209
pub name : String ,
206
- pub filters : HashMap < String , & ' a dyn Filter < Supports = Language > > ,
210
+ pub filters : HashMap < String , T > ,
207
211
}
208
212
209
- pub enum FilterType < ' a > {
210
- All ( & ' a dyn Filter < Supports = All > ) ,
211
- Many ( Many < ' a > ) ,
213
+ trait Info {
214
+ type Supported ;
215
+ fn filter_name ( & self ) -> String ;
212
216
}
213
- impl < ' a > FilterType < ' a > {
214
- fn filter_name ( & self ) -> String {
215
- todo ! ( )
216
- }
217
+ // TODO: parameterize over something that is hkt might not work
217
218
218
- fn supports ( & self ) -> SupportedLanguages {
219
- todo ! ( )
219
+ pub type FilterType < ' a > =
220
+ SingleOrMany < & ' a dyn Filter < Supports = All > , & ' a dyn Filter < Supports = Language > > ;
221
+ pub type InstantiatedFilterType =
222
+ SingleOrMany < InstantiatedFilter < All > , InstantiatedFilter < Language > > ;
223
+ pub enum SingleOrMany < A : Info < Supported = All > , M : Info < Supported = Language > > {
224
+ All ( A ) ,
225
+ Many ( Many < M > ) ,
226
+ }
227
+ impl < A : Info < Supported = All > , M : Info < Supported = Language > > SingleOrMany < A , M > {
228
+ #[ must_use]
229
+ pub fn filter_name ( & self ) -> String {
230
+ match self {
231
+ SingleOrMany :: All ( f) => f. filter_name ( ) ,
232
+ SingleOrMany :: Many ( many) => many. name . clone ( ) ,
233
+ }
220
234
}
221
235
222
- // add code here
236
+ #[ must_use]
237
+ pub fn supports ( & self ) -> SupportedLanguages {
238
+ match self {
239
+ SingleOrMany :: All ( _) => SupportedLanguages :: All ,
240
+ SingleOrMany :: Many ( many) => {
241
+ SupportedLanguages :: Many ( many. filters . keys ( ) . cloned ( ) . collect ( ) )
242
+ }
243
+ }
244
+ }
223
245
}
224
246
pub struct Filters < ' a > {
225
247
filters : HashMap < String , FilterType < ' a > > ,
226
248
}
249
+ impl < T > Info for & dyn Filter < Supports = T >
250
+ where
251
+ SupportedLanguages : From < T > ,
252
+ {
253
+ type Supported = T ;
254
+
255
+ fn filter_name ( & self ) -> String {
256
+ self . filter_info ( ) . filter_name ( ) . to_string ( )
257
+ }
258
+ }
259
+ impl < T > Info for InstantiatedFilter < T >
260
+ where
261
+ SupportedLanguages : From < T > ,
262
+ {
263
+ type Supported = T ;
264
+
265
+ fn filter_name ( & self ) -> String {
266
+ self . filter_name ( ) . to_string ( )
267
+ }
268
+ }
269
+ impl < ' a > IntoIterator for Filters < ' a > {
270
+ type Item = ( String , FilterType < ' a > ) ;
271
+
272
+ type IntoIter = hash_map:: IntoIter < String , FilterType < ' a > > ;
273
+
274
+ fn into_iter ( self ) -> Self :: IntoIter {
275
+ self . filters . into_iter ( )
276
+ }
277
+ }
227
278
228
279
impl Filters < ' static > {
280
+ #[ must_use]
229
281
pub fn default ( ) -> Self {
230
282
Self {
231
283
filters : HashMap :: from ( [
232
284
(
233
285
FunctionInLines . filter_info ( ) . filter_name ( ) . to_string ( ) ,
234
- FilterType :: All ( & FunctionInLines as & ' static dyn Filter < Supports = All > ) ,
286
+ SingleOrMany :: All ( & FunctionInLines as & ' static dyn Filter < Supports = All > ) ,
235
287
) ,
236
288
(
237
289
FunctionInImpl . filter_info ( ) . filter_name ( ) . to_string ( ) ,
238
- FilterType :: Many ( Many {
290
+ SingleOrMany :: Many ( Many {
239
291
name : "function_in_impl" . to_string ( ) ,
240
292
filters : HashMap :: from ( [ (
241
293
"Rust" . to_string ( ) ,
@@ -248,7 +300,7 @@ impl Filters<'static> {
248
300
. filter_info ( )
249
301
. filter_name ( )
250
302
. to_string ( ) ,
251
- FilterType :: Many ( Many {
303
+ SingleOrMany :: Many ( Many {
252
304
name : "function_with_parameter" . to_string ( ) ,
253
305
filters : HashMap :: from ( [ (
254
306
FunctionWithParameterRust . supports ( ) . 0 ,
@@ -264,21 +316,21 @@ impl Filters<'static> {
264
316
impl < ' a > Filters < ' a > {
265
317
pub fn add_filter ( & mut self , filter : impl Into < FilterType < ' a > > ) -> Result < ( ) , String > {
266
318
let filter = filter. into ( ) ;
267
- let name = filter. filter_name ( ) . clone ( ) ;
268
- {
269
- let this = self . filters . get_mut ( & name) ;
270
- match this {
271
- Some ( filters) => match filters {
272
- FilterType :: All ( _) => Err ( "cannot add to an all filter" . to_string ( ) ) ,
273
- FilterType :: Many ( Many { filters, .. } ) => merge_filters ( filters, filter) ,
274
- } ,
275
- None => {
276
- self . filters . insert ( name, filter) ;
277
- Ok ( ( ) )
278
- }
319
+ let name = filter. filter_name ( ) ;
320
+ if let Some ( filters) = self . filters . get_mut ( & name) {
321
+ match filters {
322
+ SingleOrMany :: All ( _) => Err ( "cannot add to an all filter" . to_string ( ) ) ,
323
+ SingleOrMany :: Many ( Many { filters, .. } ) => merge_filters ( filters, filter) ,
279
324
}
325
+ } else {
326
+ self . filters . insert ( name, filter) ;
327
+ Ok ( ( ) )
280
328
}
281
329
}
330
+ #[ must_use]
331
+ pub fn get_filter ( & self , name : & str ) -> Option < & FilterType < ' a > > {
332
+ self . filters . get ( name)
333
+ }
282
334
}
283
335
284
336
fn merge_filters < ' a > (
0 commit comments