@@ -56,6 +56,7 @@ use std::fmt;
56
56
use std:: mem;
57
57
58
58
mod op;
59
+ mod parser;
59
60
60
61
/// A builder for a log filter.
61
62
///
@@ -145,7 +146,7 @@ impl Builder {
145
146
///
146
147
/// [Enabling Logging]: ../index.html#enabling-logging
147
148
pub fn parse ( & mut self , filters : & str ) -> & mut Self {
148
- let ( directives, filter) = parse_spec ( filters) ;
149
+ let ( directives, filter) = parser :: parse_spec ( filters) ;
149
150
150
151
self . filter = filter;
151
152
@@ -281,77 +282,6 @@ impl fmt::Debug for Filter {
281
282
}
282
283
}
283
284
284
- /// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=error/foo")
285
- /// and return a vector with log directives.
286
- fn parse_spec ( spec : & str ) -> ( Vec < Directive > , Option < op:: FilterOp > ) {
287
- let mut dirs = Vec :: new ( ) ;
288
-
289
- let mut parts = spec. split ( '/' ) ;
290
- let mods = parts. next ( ) ;
291
- let filter = parts. next ( ) ;
292
- if parts. next ( ) . is_some ( ) {
293
- eprintln ! (
294
- "warning: invalid logging spec '{}', \
295
- ignoring it (too many '/'s)",
296
- spec
297
- ) ;
298
- return ( dirs, None ) ;
299
- }
300
- if let Some ( m) = mods {
301
- for s in m. split ( ',' ) . map ( |ss| ss. trim ( ) ) {
302
- if s. is_empty ( ) {
303
- continue ;
304
- }
305
- let mut parts = s. split ( '=' ) ;
306
- let ( log_level, name) =
307
- match ( parts. next ( ) , parts. next ( ) . map ( |s| s. trim ( ) ) , parts. next ( ) ) {
308
- ( Some ( part0) , None , None ) => {
309
- // if the single argument is a log-level string or number,
310
- // treat that as a global fallback
311
- match part0. parse ( ) {
312
- Ok ( num) => ( num, None ) ,
313
- Err ( _) => ( LevelFilter :: max ( ) , Some ( part0) ) ,
314
- }
315
- }
316
- ( Some ( part0) , Some ( "" ) , None ) => ( LevelFilter :: max ( ) , Some ( part0) ) ,
317
- ( Some ( part0) , Some ( part1) , None ) => match part1. parse ( ) {
318
- Ok ( num) => ( num, Some ( part0) ) ,
319
- _ => {
320
- eprintln ! (
321
- "warning: invalid logging spec '{}', \
322
- ignoring it",
323
- part1
324
- ) ;
325
- continue ;
326
- }
327
- } ,
328
- _ => {
329
- eprintln ! (
330
- "warning: invalid logging spec '{}', \
331
- ignoring it",
332
- s
333
- ) ;
334
- continue ;
335
- }
336
- } ;
337
- dirs. push ( Directive {
338
- name : name. map ( |s| s. to_string ( ) ) ,
339
- level : log_level,
340
- } ) ;
341
- }
342
- }
343
-
344
- let filter = filter. and_then ( |filter| match op:: FilterOp :: new ( filter) {
345
- Ok ( re) => Some ( re) ,
346
- Err ( e) => {
347
- eprintln ! ( "warning: invalid regex filter - {}" , e) ;
348
- None
349
- }
350
- } ) ;
351
-
352
- ( dirs, filter)
353
- }
354
-
355
285
// Check whether a level and target are enabled by the set of directives.
356
286
fn enabled ( directives : & [ Directive ] , level : Level , target : & str ) -> bool {
357
287
// Search for the longest match, the vector is assumed to be pre-sorted.
@@ -368,7 +298,7 @@ fn enabled(directives: &[Directive], level: Level, target: &str) -> bool {
368
298
mod tests {
369
299
use log:: { Level , LevelFilter } ;
370
300
371
- use super :: { enabled, parse_spec , Builder , Directive , Filter } ;
301
+ use super :: { enabled, Builder , Directive , Filter } ;
372
302
373
303
fn make_logger_filter ( dirs : Vec < Directive > ) -> Filter {
374
304
let mut logger = Builder :: new ( ) . build ( ) ;
@@ -680,183 +610,4 @@ mod tests {
680
610
assert ! ( !enabled( & logger. directives, Level :: Error , "crate1::mod1" ) ) ;
681
611
assert ! ( enabled( & logger. directives, Level :: Info , "crate2::mod2" ) ) ;
682
612
}
683
-
684
- #[ test]
685
- fn parse_spec_valid ( ) {
686
- let ( dirs, filter) = parse_spec ( "crate1::mod1=error,crate1::mod2,crate2=debug" ) ;
687
- assert_eq ! ( dirs. len( ) , 3 ) ;
688
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate1::mod1" . to_string( ) ) ) ;
689
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Error ) ;
690
-
691
- assert_eq ! ( dirs[ 1 ] . name, Some ( "crate1::mod2" . to_string( ) ) ) ;
692
- assert_eq ! ( dirs[ 1 ] . level, LevelFilter :: max( ) ) ;
693
-
694
- assert_eq ! ( dirs[ 2 ] . name, Some ( "crate2" . to_string( ) ) ) ;
695
- assert_eq ! ( dirs[ 2 ] . level, LevelFilter :: Debug ) ;
696
- assert ! ( filter. is_none( ) ) ;
697
- }
698
-
699
- #[ test]
700
- fn parse_spec_invalid_crate ( ) {
701
- // test parse_spec with multiple = in specification
702
- let ( dirs, filter) = parse_spec ( "crate1::mod1=warn=info,crate2=debug" ) ;
703
- assert_eq ! ( dirs. len( ) , 1 ) ;
704
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate2" . to_string( ) ) ) ;
705
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Debug ) ;
706
- assert ! ( filter. is_none( ) ) ;
707
- }
708
-
709
- #[ test]
710
- fn parse_spec_invalid_level ( ) {
711
- // test parse_spec with 'noNumber' as log level
712
- let ( dirs, filter) = parse_spec ( "crate1::mod1=noNumber,crate2=debug" ) ;
713
- assert_eq ! ( dirs. len( ) , 1 ) ;
714
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate2" . to_string( ) ) ) ;
715
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Debug ) ;
716
- assert ! ( filter. is_none( ) ) ;
717
- }
718
-
719
- #[ test]
720
- fn parse_spec_string_level ( ) {
721
- // test parse_spec with 'warn' as log level
722
- let ( dirs, filter) = parse_spec ( "crate1::mod1=wrong,crate2=warn" ) ;
723
- assert_eq ! ( dirs. len( ) , 1 ) ;
724
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate2" . to_string( ) ) ) ;
725
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Warn ) ;
726
- assert ! ( filter. is_none( ) ) ;
727
- }
728
-
729
- #[ test]
730
- fn parse_spec_empty_level ( ) {
731
- // test parse_spec with '' as log level
732
- let ( dirs, filter) = parse_spec ( "crate1::mod1=wrong,crate2=" ) ;
733
- assert_eq ! ( dirs. len( ) , 1 ) ;
734
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate2" . to_string( ) ) ) ;
735
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: max( ) ) ;
736
- assert ! ( filter. is_none( ) ) ;
737
- }
738
-
739
- #[ test]
740
- fn parse_spec_empty_level_isolated ( ) {
741
- // test parse_spec with "" as log level (and the entire spec str)
742
- let ( dirs, filter) = parse_spec ( "" ) ; // should be ignored
743
- assert_eq ! ( dirs. len( ) , 0 ) ;
744
- assert ! ( filter. is_none( ) ) ;
745
- }
746
-
747
- #[ test]
748
- fn parse_spec_blank_level_isolated ( ) {
749
- // test parse_spec with a white-space-only string specified as the log
750
- // level (and the entire spec str)
751
- let ( dirs, filter) = parse_spec ( " " ) ; // should be ignored
752
- assert_eq ! ( dirs. len( ) , 0 ) ;
753
- assert ! ( filter. is_none( ) ) ;
754
- }
755
-
756
- #[ test]
757
- fn parse_spec_blank_level_isolated_comma_only ( ) {
758
- // The spec should contain zero or more comma-separated string slices,
759
- // so a comma-only string should be interpreted as two empty strings
760
- // (which should both be treated as invalid, so ignored).
761
- let ( dirs, filter) = parse_spec ( "," ) ; // should be ignored
762
- assert_eq ! ( dirs. len( ) , 0 ) ;
763
- assert ! ( filter. is_none( ) ) ;
764
- }
765
-
766
- #[ test]
767
- fn parse_spec_blank_level_isolated_comma_blank ( ) {
768
- // The spec should contain zero or more comma-separated string slices,
769
- // so this bogus spec should be interpreted as containing one empty
770
- // string and one blank string. Both should both be treated as
771
- // invalid, so ignored.
772
- let ( dirs, filter) = parse_spec ( ", " ) ; // should be ignored
773
- assert_eq ! ( dirs. len( ) , 0 ) ;
774
- assert ! ( filter. is_none( ) ) ;
775
- }
776
-
777
- #[ test]
778
- fn parse_spec_blank_level_isolated_blank_comma ( ) {
779
- // The spec should contain zero or more comma-separated string slices,
780
- // so this bogus spec should be interpreted as containing one blank
781
- // string and one empty string. Both should both be treated as
782
- // invalid, so ignored.
783
- let ( dirs, filter) = parse_spec ( " ," ) ; // should be ignored
784
- assert_eq ! ( dirs. len( ) , 0 ) ;
785
- assert ! ( filter. is_none( ) ) ;
786
- }
787
-
788
- #[ test]
789
- fn parse_spec_global ( ) {
790
- // test parse_spec with no crate
791
- let ( dirs, filter) = parse_spec ( "warn,crate2=debug" ) ;
792
- assert_eq ! ( dirs. len( ) , 2 ) ;
793
- assert_eq ! ( dirs[ 0 ] . name, None ) ;
794
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Warn ) ;
795
- assert_eq ! ( dirs[ 1 ] . name, Some ( "crate2" . to_string( ) ) ) ;
796
- assert_eq ! ( dirs[ 1 ] . level, LevelFilter :: Debug ) ;
797
- assert ! ( filter. is_none( ) ) ;
798
- }
799
-
800
- #[ test]
801
- fn parse_spec_global_bare_warn_lc ( ) {
802
- // test parse_spec with no crate, in isolation, all lowercase
803
- let ( dirs, filter) = parse_spec ( "warn" ) ;
804
- assert_eq ! ( dirs. len( ) , 1 ) ;
805
- assert_eq ! ( dirs[ 0 ] . name, None ) ;
806
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Warn ) ;
807
- assert ! ( filter. is_none( ) ) ;
808
- }
809
-
810
- #[ test]
811
- fn parse_spec_global_bare_warn_uc ( ) {
812
- // test parse_spec with no crate, in isolation, all uppercase
813
- let ( dirs, filter) = parse_spec ( "WARN" ) ;
814
- assert_eq ! ( dirs. len( ) , 1 ) ;
815
- assert_eq ! ( dirs[ 0 ] . name, None ) ;
816
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Warn ) ;
817
- assert ! ( filter. is_none( ) ) ;
818
- }
819
-
820
- #[ test]
821
- fn parse_spec_global_bare_warn_mixed ( ) {
822
- // test parse_spec with no crate, in isolation, mixed case
823
- let ( dirs, filter) = parse_spec ( "wArN" ) ;
824
- assert_eq ! ( dirs. len( ) , 1 ) ;
825
- assert_eq ! ( dirs[ 0 ] . name, None ) ;
826
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Warn ) ;
827
- assert ! ( filter. is_none( ) ) ;
828
- }
829
-
830
- #[ test]
831
- fn parse_spec_valid_filter ( ) {
832
- let ( dirs, filter) = parse_spec ( "crate1::mod1=error,crate1::mod2,crate2=debug/abc" ) ;
833
- assert_eq ! ( dirs. len( ) , 3 ) ;
834
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate1::mod1" . to_string( ) ) ) ;
835
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Error ) ;
836
-
837
- assert_eq ! ( dirs[ 1 ] . name, Some ( "crate1::mod2" . to_string( ) ) ) ;
838
- assert_eq ! ( dirs[ 1 ] . level, LevelFilter :: max( ) ) ;
839
-
840
- assert_eq ! ( dirs[ 2 ] . name, Some ( "crate2" . to_string( ) ) ) ;
841
- assert_eq ! ( dirs[ 2 ] . level, LevelFilter :: Debug ) ;
842
- assert ! ( filter. is_some( ) && filter. unwrap( ) . to_string( ) == "abc" ) ;
843
- }
844
-
845
- #[ test]
846
- fn parse_spec_invalid_crate_filter ( ) {
847
- let ( dirs, filter) = parse_spec ( "crate1::mod1=error=warn,crate2=debug/a.c" ) ;
848
- assert_eq ! ( dirs. len( ) , 1 ) ;
849
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate2" . to_string( ) ) ) ;
850
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: Debug ) ;
851
- assert ! ( filter. is_some( ) && filter. unwrap( ) . to_string( ) == "a.c" ) ;
852
- }
853
-
854
- #[ test]
855
- fn parse_spec_empty_with_filter ( ) {
856
- let ( dirs, filter) = parse_spec ( "crate1/a*c" ) ;
857
- assert_eq ! ( dirs. len( ) , 1 ) ;
858
- assert_eq ! ( dirs[ 0 ] . name, Some ( "crate1" . to_string( ) ) ) ;
859
- assert_eq ! ( dirs[ 0 ] . level, LevelFilter :: max( ) ) ;
860
- assert ! ( filter. is_some( ) && filter. unwrap( ) . to_string( ) == "a*c" ) ;
861
- }
862
613
}
0 commit comments