11use 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+ } ;
37
48mod filter_parsers;
59mod general_filters;
@@ -36,15 +40,9 @@ use crate::SupportedLanguages;
3640pub trait Filter : HasFilterInformation {
3741 fn parse_filter ( & self , s : & str ) -> Result < FilterFunction , String > ;
3842 // 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 > {
4044 let filter = self . parse_filter ( s) ?;
4145 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- } ;
4846 Ok ( InstantiatedFilter {
4947 filter_information : info,
5048 filter_function : filter,
@@ -130,32 +128,37 @@ type FilterFunction = Box<dyn Fn(&Node<'_>) -> bool + Send + Sync>;
130128// TODO: make our own FromStr that also requires the proggramer to sepcify that attributes each
131129// filter has and their type so that we can make macro that creates parser, and also so that we can
132130// 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 > ,
135134 filter_function : FilterFunction ,
136135}
137136
138- impl PartialEq for InstantiatedFilter {
137+ impl < Supports : PartialEq > PartialEq for InstantiatedFilter < Supports > {
139138 fn eq ( & self , other : & Self ) -> bool {
140139 self . filter_information == other. filter_information
141140 }
141+
142+ fn ne ( & self , other : & Self ) -> bool {
143+ !self . eq ( other)
144+ }
142145}
143- impl Eq for InstantiatedFilter { }
146+ impl < Supports : PartialEq > Eq for InstantiatedFilter < Supports > { }
144147
145- impl fmt:: Display for InstantiatedFilter {
148+ impl < Supports > fmt:: Display for InstantiatedFilter < Supports > {
146149 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
147150 write ! ( f, "{}" , self . filter_information)
148151 }
149152}
150- impl std:: fmt:: Debug for InstantiatedFilter {
153+ impl < Supports : std:: fmt:: Debug > std :: fmt :: Debug for InstantiatedFilter < Supports > {
151154 fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
152155 f. debug_struct ( "InstantiatedFilter" )
153156 . field ( "filter_information" , & self . filter_information )
154157 . finish ( )
155158 }
156159}
157160
158- impl InstantiatedFilter {
161+ impl < Supports > InstantiatedFilter < Supports > {
159162 #[ must_use]
160163 pub fn filter ( & self , node : & Node < ' _ > ) -> bool {
161164 ( self . filter_function ) ( node)
@@ -177,7 +180,7 @@ impl InstantiatedFilter {
177180 }
178181
179182 #[ must_use]
180- pub const fn supported_languages ( & self ) -> & SupportedLanguages {
183+ pub const fn supported_languages ( & self ) -> & Supports {
181184 self . filter_information . supported_languages ( )
182185 }
183186}
@@ -196,46 +199,95 @@ impl From<Language> for SupportedLanguages {
196199 }
197200}
198201// impl Language for
202+ // TODO: rework macro to work with the new language per filter system
199203macro_rules! default_filters {
200204 ( $( $filter: ident) ,* ) => { S
201205 HashMap :: from( [ $( ( $filter. filter_info( ) . filter_name( ) . to_string( ) , & $filter as & ' static dyn Filter ) ) ,* ] )
202206 } ;
203207}
204- pub struct Many < ' a > {
208+ pub struct Many < T : Info < Supported = Language > > {
205209 pub name : String ,
206- pub filters : HashMap < String , & ' a dyn Filter < Supports = Language > > ,
210+ pub filters : HashMap < String , T > ,
207211}
208212
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 ;
212216}
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
217218
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+ }
220234 }
221235
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+ }
223245}
224246pub struct Filters < ' a > {
225247 filters : HashMap < String , FilterType < ' a > > ,
226248}
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+ }
227278
228279impl Filters < ' static > {
280+ #[ must_use]
229281 pub fn default ( ) -> Self {
230282 Self {
231283 filters : HashMap :: from ( [
232284 (
233285 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 > ) ,
235287 ) ,
236288 (
237289 FunctionInImpl . filter_info ( ) . filter_name ( ) . to_string ( ) ,
238- FilterType :: Many ( Many {
290+ SingleOrMany :: Many ( Many {
239291 name : "function_in_impl" . to_string ( ) ,
240292 filters : HashMap :: from ( [ (
241293 "Rust" . to_string ( ) ,
@@ -248,7 +300,7 @@ impl Filters<'static> {
248300 . filter_info ( )
249301 . filter_name ( )
250302 . to_string ( ) ,
251- FilterType :: Many ( Many {
303+ SingleOrMany :: Many ( Many {
252304 name : "function_with_parameter" . to_string ( ) ,
253305 filters : HashMap :: from ( [ (
254306 FunctionWithParameterRust . supports ( ) . 0 ,
@@ -264,21 +316,21 @@ impl Filters<'static> {
264316impl < ' a > Filters < ' a > {
265317 pub fn add_filter ( & mut self , filter : impl Into < FilterType < ' a > > ) -> Result < ( ) , String > {
266318 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) ,
279324 }
325+ } else {
326+ self . filters . insert ( name, filter) ;
327+ Ok ( ( ) )
280328 }
281329 }
330+ #[ must_use]
331+ pub fn get_filter ( & self , name : & str ) -> Option < & FilterType < ' a > > {
332+ self . filters . get ( name)
333+ }
282334}
283335
284336fn merge_filters < ' a > (
0 commit comments