@@ -200,6 +200,11 @@ impl From<Language> for SupportedLanguages {
200200 Self :: Single ( value. 0 )
201201 }
202202}
203+ impl fmt:: Display for Language {
204+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
205+ write ! ( f, "{}" , self . 0 )
206+ }
207+ }
203208// impl Language for
204209// TODO: rework macro to work with the new language per filter system
205210macro_rules! default_filters {
@@ -213,6 +218,7 @@ pub struct Many<T: Info<Supported = Language>> {
213218 pub filters : HashMap < String , T > ,
214219}
215220
221+ // TODO: merge with HasFilterInformation
216222pub trait Info {
217223 type Supported ;
218224 fn filter_name ( & self ) -> String ;
@@ -242,10 +248,10 @@ impl<A: Info<Supported = All>, M: Info<Supported = Language>> SingleOrMany<A, M>
242248 #[ must_use]
243249 pub fn supports ( & self ) -> SupportedLanguages {
244250 match self {
245- // Self::Single(s) => SupportedLanguages::Single(s.)
246251 Self :: All ( _) => SupportedLanguages :: All ,
247252 Self :: Many ( many) => SupportedLanguages :: Many ( many. filters . keys ( ) . cloned ( ) . collect ( ) ) ,
248- SingleOrMany :: Single ( _) => todo ! ( ) ,
253+ // TODO: make Info carry not just the supported type but also a value for it
254+ Self :: Single ( _s) => todo ! ( ) ,
249255 }
250256 }
251257}
@@ -255,6 +261,7 @@ impl<A: Info<Supported = All>, M: Info<Supported = Language>> Display for Single
255261 }
256262}
257263impl < ' a > FilterType < ' a > {
264+ #[ must_use]
258265 pub fn specific ( & self , s : & str ) -> Option < Self > {
259266 match self {
260267 Self :: All ( _) | Self :: Single ( _) => None ,
@@ -351,19 +358,43 @@ impl Filters<'static> {
351358
352359impl < ' a > Filters < ' a > {
353360 pub fn add_filter ( & mut self , filter : impl Into < FilterType < ' a > > ) -> Result < ( ) , String > {
354- let filter = filter. into ( ) ;
361+ let filter: FilterType < ' a > = filter. into ( ) ;
355362 let name = filter. filter_name ( ) ;
356363 if let Some ( filters) = self . filters . get_mut ( & name) {
357364 match filters {
358- SingleOrMany :: All ( _) => Err ( "cannot add to an all filter" . to_string ( ) ) ,
359- SingleOrMany :: Many ( Many { filters, .. } ) => merge_filters ( filters, filter) ,
360- SingleOrMany :: Single ( s) => {
361- * filters = SingleOrMany :: Many ( Many {
362- name : "" . to_string ( ) ,
363- filters : HashMap :: from ( [ ( s. filter_name ( ) , * s) ] ) ,
364- } ) ;
365- Ok ( ( ) )
365+ SingleOrMany :: All ( _) => Err ( "cannot add with or to an all filter" . to_string ( ) ) ,
366+ _ if matches ! ( filter, SingleOrMany :: All ( _) ) => {
367+ Err ( "cannot add with or to an all filter" . to_string ( ) )
366368 }
369+ SingleOrMany :: Many ( filter1) => match filter {
370+ SingleOrMany :: All ( _) => unreachable ! ( ) ,
371+ SingleOrMany :: Many ( filter2) => try_extend_filter ( filter1, filter2) ,
372+ SingleOrMany :: Single ( filter2) => try_add_filter ( filter1, filter2) ,
373+ } ,
374+ SingleOrMany :: Single ( filter1) => match filter {
375+ SingleOrMany :: All ( _) => unreachable ! ( ) ,
376+ SingleOrMany :: Many ( mut filter2) => {
377+ try_add_filter ( & mut filter2, * filter1) ?;
378+ * filters = SingleOrMany :: Many ( filter2) ;
379+ Ok ( ( ) )
380+ }
381+ SingleOrMany :: Single ( filter2) if filter1. supports ( ) == filter2. supports ( ) => {
382+ Err ( format ! (
383+ "cannot add duplicate filter {name} for {}" ,
384+ filter1. supports( )
385+ ) )
386+ }
387+ SingleOrMany :: Single ( filter2) => {
388+ * filters = SingleOrMany :: Many ( Many {
389+ name,
390+ filters : HashMap :: from ( [
391+ ( filter1. supports ( ) . 0 , * filter1) ,
392+ ( filter2. supports ( ) . 0 , filter2) ,
393+ ] ) ,
394+ } ) ;
395+ Ok ( ( ) )
396+ }
397+ } ,
367398 }
368399 } else {
369400 self . filters . insert ( name, filter) ;
@@ -376,9 +407,31 @@ impl<'a> Filters<'a> {
376407 }
377408}
378409
379- fn merge_filters < ' a > (
380- hash_map : & mut HashMap < String , & ' a dyn Filter < Supports = Language > > ,
381- filter : FilterType < ' a > ,
410+ fn try_add_filter < ' a > (
411+ filters : & mut Many < & ' a ( dyn Filter < Supports = Language > ) > ,
412+ filter : & ' a ( dyn Filter < Supports = Language > ) ,
413+ ) -> Result < ( ) , String > {
414+ let mut status = Ok ( ( ) ) ;
415+ filters
416+ . filters
417+ . entry ( filter. supports ( ) . 0 )
418+ . and_modify ( |_| {
419+ status = Err ( format ! (
420+ "cannot add duplicate filter {} for {}" ,
421+ filter. filter_name( ) ,
422+ filter. supports( )
423+ ) ) ;
424+ } )
425+ . or_insert ( filter) ;
426+ status
427+ }
428+
429+ fn try_extend_filter < ' a > (
430+ filters : & mut Many < & ' a ( dyn Filter < Supports = Language > ) > ,
431+ new_filters : Many < & ' a ( dyn Filter < Supports = Language > ) > ,
382432) -> Result < ( ) , String > {
383- todo ! ( )
433+ new_filters
434+ . filters
435+ . into_values ( )
436+ . try_for_each ( |filter| try_add_filter ( filters, filter) )
384437}
0 commit comments