@@ -200,6 +200,11 @@ impl From<Language> for SupportedLanguages {
200
200
Self :: Single ( value. 0 )
201
201
}
202
202
}
203
+ impl fmt:: Display for Language {
204
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
205
+ write ! ( f, "{}" , self . 0 )
206
+ }
207
+ }
203
208
// impl Language for
204
209
// TODO: rework macro to work with the new language per filter system
205
210
macro_rules! default_filters {
@@ -213,6 +218,7 @@ pub struct Many<T: Info<Supported = Language>> {
213
218
pub filters : HashMap < String , T > ,
214
219
}
215
220
221
+ // TODO: merge with HasFilterInformation
216
222
pub trait Info {
217
223
type Supported ;
218
224
fn filter_name ( & self ) -> String ;
@@ -242,10 +248,10 @@ impl<A: Info<Supported = All>, M: Info<Supported = Language>> SingleOrMany<A, M>
242
248
#[ must_use]
243
249
pub fn supports ( & self ) -> SupportedLanguages {
244
250
match self {
245
- // Self::Single(s) => SupportedLanguages::Single(s.)
246
251
Self :: All ( _) => SupportedLanguages :: All ,
247
252
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 ! ( ) ,
249
255
}
250
256
}
251
257
}
@@ -255,6 +261,7 @@ impl<A: Info<Supported = All>, M: Info<Supported = Language>> Display for Single
255
261
}
256
262
}
257
263
impl < ' a > FilterType < ' a > {
264
+ #[ must_use]
258
265
pub fn specific ( & self , s : & str ) -> Option < Self > {
259
266
match self {
260
267
Self :: All ( _) | Self :: Single ( _) => None ,
@@ -351,19 +358,43 @@ impl Filters<'static> {
351
358
352
359
impl < ' a > Filters < ' a > {
353
360
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 ( ) ;
355
362
let name = filter. filter_name ( ) ;
356
363
if let Some ( filters) = self . filters . get_mut ( & name) {
357
364
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 ( ) )
366
368
}
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
+ } ,
367
398
}
368
399
} else {
369
400
self . filters . insert ( name, filter) ;
@@ -376,9 +407,31 @@ impl<'a> Filters<'a> {
376
407
}
377
408
}
378
409
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 > ) > ,
382
432
) -> Result < ( ) , String > {
383
- todo ! ( )
433
+ new_filters
434
+ . filters
435
+ . into_values ( )
436
+ . try_for_each ( |filter| try_add_filter ( filters, filter) )
384
437
}
0 commit comments