1
1
mod types;
2
2
3
- use std:: { collections:: HashMap , sync:: mpsc, time:: Duration } ;
3
+ use std:: { collections:: HashMap , fmt , sync:: mpsc, time:: Duration } ;
4
4
5
5
use eframe:: {
6
6
self ,
7
- egui:: { self , Button , Label , Layout , Sense , SidePanel , TextEdit , TopBottomPanel , Visuals } ,
7
+ egui:: {
8
+ self , Button , Label , Layout , Sense , SidePanel , TextBuffer , TextEdit , TopBottomPanel ,
9
+ Visuals ,
10
+ } ,
8
11
epaint:: { Color32 , Vec2 } ,
9
12
} ;
10
13
use function_history_backend_thread:: types:: {
@@ -250,6 +253,57 @@ impl MyEguiApp {
250
253
} ) ;
251
254
}
252
255
}
256
+ fn handle_many_filter (
257
+ inputs : & mut HashMap < String , ( bool , String ) > ,
258
+ ui : & mut egui:: Ui ,
259
+ max : f32 ,
260
+ next_field : & mut String ,
261
+ specific : & mut Option < String > ,
262
+ languages : & Vec < String > ,
263
+ filters : & function_grep:: filter:: FilterType < ' static > ,
264
+ ) -> Result < Option < PLFilter > , String > {
265
+ // TODO: cleanup
266
+ inputs. iter_mut ( ) . for_each ( |( desc, field) | {
267
+ ui. horizontal ( |ui| {
268
+ ui. set_min_width ( 4.0 ) ;
269
+ ui. set_max_width ( max) ;
270
+ ui. label ( desc. to_string ( ) ) ;
271
+ ui. add ( TextEdit :: singleline ( & mut field. 1 ) ) ;
272
+ // TODO: make - work
273
+ field. 0 = ui. add ( Button :: new ( "-" ) ) . clicked ( ) ;
274
+ } ) ;
275
+ } ) ;
276
+ ui. add ( TextEdit :: singleline ( next_field) ) ;
277
+ let resp = ui. add ( Button :: new ( "add field" ) ) ;
278
+ if resp. clicked ( ) {
279
+ inputs. insert ( next_field. to_string ( ) , ( false , String :: new ( ) ) ) ;
280
+ }
281
+ egui:: ComboBox :: from_id_source ( "filter_language_chooser" )
282
+ . selected_text ( "Language" )
283
+ . show_ui ( ui, |ui| {
284
+ ui. selectable_value ( specific, None , "All" ) ;
285
+ languages. iter ( ) . for_each ( |name| {
286
+ ui. selectable_value ( specific, Some ( name. to_string ( ) ) , name) ;
287
+ } ) ;
288
+ } ) ;
289
+ if let Some ( language) = specific {
290
+ {
291
+ match filters. specific ( language) {
292
+ Some ( filter @ function_grep:: filter:: SingleOrMany :: Single ( single_filter) ) => {
293
+ Ok ( Some ( instantiate_single_filter_state_inner (
294
+ single_filter,
295
+ filter,
296
+ ) ) )
297
+ }
298
+ _ => Err ( format ! (
299
+ "Filter {filters} does not support Language {language}."
300
+ ) ) ,
301
+ }
302
+ }
303
+ } else {
304
+ Ok ( None )
305
+ }
306
+ }
253
307
}
254
308
macro_rules! draw_text_input {
255
309
( $ui: expr, $max: expr, $( $field: expr) +) => { {
@@ -398,13 +452,17 @@ impl eframe::App for MyEguiApp {
398
452
HistoryFilterType :: None ,
399
453
"none" ,
400
454
) ;
401
- function_grep:: filter:: Filters :: default ( ) . into_iter ( ) . sorted_by_cached_key ( |( key, _) | { key. clone ( ) } ) . for_each ( |filter| { ui. selectable_value ( & mut self . history_filter_type , match filter. 1 { function_grep:: filter:: FilterType :: All ( allfilter) => { HistoryFilterType :: PL ( types:: PLFilter :: Single ( allfilter . attributes ( ) . into_iter ( ) . map ( |( attr, kind) | { ( attr. to_string ( ) , kind. to_string ( ) , ) } ) . collect ( ) , filter. 1 ) ) } function_grep:: filter:: FilterType :: Single ( allfilter) => { HistoryFilterType :: PL ( types:: PLFilter :: Single ( allfilter . attributes ( ) . into_iter ( ) . map ( |( attr, kind) | { ( attr. to_string ( ) , kind. to_string ( ) , ) } ) . collect ( ) , filter. 1 ) ) }
402
-
403
-
404
- function_grep:: filter:: SingleOrMany :: Many ( ref filters) => {
405
- let collect_vec = filters. filters . keys ( ) . cloned ( ) . collect_vec ( ) ;
406
- HistoryFilterType :: PL ( types:: PLFilter :: Many ( HashMap :: new ( ) , filter. 1 , collect_vec, None , String :: new ( ) ) )
407
- } } , filter. 0 , ) ;
455
+ function_grep:: filter:: Filters :: default ( )
456
+ . into_iter ( )
457
+ . sorted_by_cached_key ( |( key, _) | {
458
+ key. clone ( )
459
+ } )
460
+ . for_each ( |filter| {
461
+ ui. selectable_value (
462
+ & mut self . history_filter_type ,
463
+ initialize_filter_state ( filter. 1 ) ,
464
+ filter. 0 ,
465
+ ) ;
408
466
} )
409
467
} ) ;
410
468
match & mut self . history_filter_type {
@@ -421,52 +479,33 @@ impl eframe::App for MyEguiApp {
421
479
HistoryFilterType :: None => {
422
480
// do nothing
423
481
}
424
- HistoryFilterType :: PL ( filter ) => {
425
- match filter {
426
- types:: PLFilter :: Single ( inputs, _) => {
427
- inputs. iter_mut ( ) . for_each ( |( desc, field ) | {
428
- ui. horizontal ( |ui| {
429
- ui. set_min_width ( 4.0 ) ;
430
- ui. set_max_width ( max) ;
431
- ui. label ( desc. to_string ( ) ) ;
432
- ui. add ( TextEdit :: singleline ( field) ) ;
433
- } ) ;
434
- } ) ;
435
- }
436
- types:: PLFilter :: Many ( inputs, filters, languages, specific, next_field ) => {
437
- // TODO: cleanup
438
- inputs. iter_mut ( ) . for_each ( |( desc, field ) | {
439
- ui. horizontal ( |ui| {
440
- ui. set_min_width ( 4.0 ) ;
441
- ui. set_max_width ( max) ;
442
- ui. label ( desc. to_string ( ) ) ;
443
- ui. add ( TextEdit :: singleline ( & mut field. 1 ) ) ;
444
- // TODO: make - work
445
- field. 0 = ui. add ( Button :: new ( "-" ) ) . clicked ( ) ;
446
- } ) ;
447
- } ) ;
448
-
449
- ui. add ( TextEdit :: singleline ( next_field) ) ;
450
- let resp = ui. add ( Button :: new ( "add field" ) ) ;
451
- if resp. clicked ( ) {
452
- inputs. insert ( next_field. to_string ( ) , ( false , String :: new ( ) ) ) ;
453
- }
454
-
455
- egui:: ComboBox :: from_id_source ( "filter_language_chooser" )
456
- . selected_text ( "Language" )
457
- . show_ui ( ui, |ui| {
458
- ui. selectable_value (
459
- specific, None , "All" ) ;
460
- languages. iter ( ) . for_each ( |name| { ui. selectable_value ( specific, Some ( name. to_string ( ) ) , name) ; } ) ;
461
- }
462
-
463
- ) ;
464
- if let Some ( language) = specific {
465
- * filter = PLFilter :: Single ( HashMap :: new ( ) , filters. specific ( language) . unwrap ( ) ) ;
482
+ HistoryFilterType :: PL ( filter) => match filter {
483
+ types:: PLFilter :: Single ( inputs, _) => {
484
+ handle_single_filter ( inputs, ui, max) ;
485
+ }
486
+ types:: PLFilter :: Many (
487
+ inputs,
488
+ filters,
489
+ languages,
490
+ specific,
491
+ next_field,
492
+ ) => {
493
+ let result = Self :: handle_many_filter (
494
+ inputs, ui, max, next_field, specific,
495
+ languages, filters,
496
+ ) ;
497
+ match result {
498
+ Ok ( Some ( new_filter) ) => {
499
+ * filter = new_filter
466
500
}
467
-
468
- }
469
- } } }
501
+ Ok ( _) => { }
502
+ Err ( e) => {
503
+ self . status = Status :: Error ( e)
504
+ }
505
+ }
506
+ }
507
+ } ,
508
+ }
470
509
let resp = ui. add ( Button :: new ( "Go" ) ) ;
471
510
if resp. clicked ( ) {
472
511
self . status = Status :: Loading ;
@@ -500,10 +539,26 @@ impl eframe::App for MyEguiApp {
500
539
}
501
540
HistoryFilterType :: PL ( filter) => {
502
541
let filter = match filter {
503
- types:: PLFilter :: Single ( hash_map, single_or_many) => single_or_many. to_filter ( & hash_map. into_iter ( ) . map ( |v| format ! ( "{}: {}" , v. 0 , v. 1 ) ) . collect_vec ( ) . join ( " " ) ) ,
504
- types:: PLFilter :: Many ( input, filter, _, _, _) =>
505
- filter. to_filter ( & input. into_iter ( ) . map ( |v| format ! ( "{}: {}" , v. 0 , v. 1.1 ) ) . collect_vec ( ) . join ( " " ) )
542
+ types:: PLFilter :: Single (
543
+ input,
544
+ filter,
545
+ ) => instantiate_filter (
546
+ filter,
547
+ input. iter ( ) ,
548
+ ) ,
506
549
550
+ types:: PLFilter :: Many (
551
+ input,
552
+ filter,
553
+ _,
554
+ _,
555
+ _,
556
+ ) => instantiate_filter (
557
+ filter,
558
+ input
559
+ . iter ( )
560
+ . map ( |( k, ( _, v) ) | ( k, v) ) ,
561
+ ) ,
507
562
} ;
508
563
filter
509
564
. inspect_err ( |e| {
@@ -770,3 +825,91 @@ impl eframe::App for MyEguiApp {
770
825
}
771
826
}
772
827
}
828
+
829
+ fn instantiate_filter (
830
+ filter : & function_grep:: filter:: FilterType < ' static > ,
831
+ input : impl Iterator < Item = ( impl fmt:: Display , impl fmt:: Display ) > ,
832
+ ) -> Result < function_grep:: filter:: InstantiatedFilterType , String > {
833
+ filter. to_filter (
834
+ & input
835
+ . map ( |v| format ! ( "{}: {}" , v. 0 , v. 1 ) )
836
+ . collect_vec ( )
837
+ . join ( " " ) ,
838
+ )
839
+ }
840
+
841
+ fn handle_single_filter ( inputs : & mut HashMap < String , String > , ui : & mut egui:: Ui , max : f32 ) {
842
+ inputs. iter_mut ( ) . for_each ( |( desc, field) | {
843
+ ui. horizontal ( |ui| {
844
+ ui. set_min_width ( 4.0 ) ;
845
+ ui. set_max_width ( max) ;
846
+ ui. label ( desc. to_string ( ) ) ;
847
+ ui. add ( TextEdit :: singleline ( field) ) ;
848
+ } ) ;
849
+ } ) ;
850
+ }
851
+
852
+ fn initialize_filter_state (
853
+ filter : function_grep:: filter:: FilterType < ' static > ,
854
+ ) -> HistoryFilterType {
855
+ match filter {
856
+ function_grep:: filter:: FilterType :: All ( all_filter) => {
857
+ instantiate_single_filter_state ( all_filter, filter)
858
+ }
859
+ function_grep:: filter:: FilterType :: Single ( single_filter) => {
860
+ instantiate_single_filter_state ( single_filter, filter)
861
+ }
862
+
863
+ function_grep:: filter:: SingleOrMany :: Many ( ref filters) => {
864
+ let single_filter = filters
865
+ . filters
866
+ . keys ( )
867
+ . next ( )
868
+ . filter ( |_| filters. filters . len ( ) == 1 )
869
+ . and_then ( |k| filter. specific ( k) ) ;
870
+ match single_filter {
871
+ Some ( filter @ function_grep:: filter:: SingleOrMany :: Single ( single_filter) ) => {
872
+ instantiate_single_filter_state ( single_filter, filter)
873
+ }
874
+ _ => {
875
+ let collect_vec = filters. filters . keys ( ) . cloned ( ) . collect_vec ( ) ;
876
+
877
+ HistoryFilterType :: PL ( types:: PLFilter :: Many (
878
+ HashMap :: new ( ) ,
879
+ filter,
880
+ collect_vec,
881
+ None ,
882
+ String :: new ( ) ,
883
+ ) )
884
+ }
885
+ }
886
+ }
887
+ }
888
+ }
889
+
890
+ fn instantiate_single_filter_state < T > (
891
+ allfilter : & ( dyn function_grep:: filter:: Filter < Supports = T > ) ,
892
+ filter : function_grep:: filter:: FilterType < ' static > ,
893
+ ) -> HistoryFilterType
894
+ where
895
+ function_grep:: SupportedLanguages : From < T > ,
896
+ {
897
+ HistoryFilterType :: PL ( instantiate_single_filter_state_inner ( allfilter, filter) )
898
+ }
899
+
900
+ fn instantiate_single_filter_state_inner < T > (
901
+ allfilter : & ( dyn function_grep:: filter:: Filter < Supports = T > ) ,
902
+ filter : function_grep:: filter:: FilterType < ' static > ,
903
+ ) -> PLFilter
904
+ where
905
+ function_grep:: SupportedLanguages : From < T > ,
906
+ {
907
+ types:: PLFilter :: Single (
908
+ allfilter
909
+ . attributes ( )
910
+ . into_iter ( )
911
+ . map ( |( attr, kind) | ( attr. to_string ( ) , kind. to_string ( ) ) )
912
+ . collect ( ) ,
913
+ filter,
914
+ )
915
+ }
0 commit comments