40
40
//! - `-vvv` show debug
41
41
//! - `-vvvv` show trace
42
42
//!
43
- //! You can also customize the default logging level:
43
+ //! By default, the log level is set to Error. To customize this to a different level, pass a type
44
+ //! implementing the [`LogLevel`] trait to [`Verbosity`]:
45
+ //!
44
46
//! ```rust,no_run
45
47
//! # use clap::Parser;
46
48
//! use clap_verbosity_flag::{Verbosity, InfoLevel};
@@ -190,7 +192,6 @@ pub trait LogLevel {
190
192
}
191
193
192
194
/// Default to [`log::Level::Error`]
193
- #[ allow( clippy:: exhaustive_structs) ]
194
195
#[ derive( Copy , Clone , Debug , Default ) ]
195
196
pub struct ErrorLevel ;
196
197
@@ -201,7 +202,6 @@ impl LogLevel for ErrorLevel {
201
202
}
202
203
203
204
/// Default to [`log::Level::Warn`]
204
- #[ allow( clippy:: exhaustive_structs) ]
205
205
#[ derive( Copy , Clone , Debug , Default ) ]
206
206
pub struct WarnLevel ;
207
207
@@ -212,7 +212,6 @@ impl LogLevel for WarnLevel {
212
212
}
213
213
214
214
/// Default to [`log::Level::Info`]
215
- #[ allow( clippy:: exhaustive_structs) ]
216
215
#[ derive( Copy , Clone , Debug , Default ) ]
217
216
pub struct InfoLevel ;
218
217
@@ -222,6 +221,36 @@ impl LogLevel for InfoLevel {
222
221
}
223
222
}
224
223
224
+ /// Default to [`log::Level::Debug`]
225
+ #[ derive( Copy , Clone , Debug , Default ) ]
226
+ pub struct DebugLevel ;
227
+
228
+ impl LogLevel for DebugLevel {
229
+ fn default ( ) -> Option < Level > {
230
+ Some ( Level :: Debug )
231
+ }
232
+ }
233
+
234
+ /// Default to [`log::Level::Trace`]
235
+ #[ derive( Copy , Clone , Debug , Default ) ]
236
+ pub struct TraceLevel ;
237
+
238
+ impl LogLevel for TraceLevel {
239
+ fn default ( ) -> Option < Level > {
240
+ Some ( Level :: Trace )
241
+ }
242
+ }
243
+
244
+ /// Default to no logging (i.e. `None` or [`log::LevelFilter::Off`])
245
+ #[ derive( Copy , Clone , Debug , Default ) ]
246
+ pub struct OffLevel ;
247
+
248
+ impl LogLevel for OffLevel {
249
+ fn default ( ) -> Option < Level > {
250
+ None
251
+ }
252
+ }
253
+
225
254
#[ cfg( test) ]
226
255
mod test {
227
256
use super :: * ;
@@ -238,6 +267,38 @@ mod test {
238
267
Cli :: command ( ) . debug_assert ( ) ;
239
268
}
240
269
270
+ #[ test]
271
+ fn verbosity_off_level ( ) {
272
+ let tests = [
273
+ // verbose, quiet, expected_level, expected_filter
274
+ ( 0 , 0 , None , LevelFilter :: Off ) ,
275
+ ( 1 , 0 , Some ( Level :: Error ) , LevelFilter :: Error ) ,
276
+ ( 2 , 0 , Some ( Level :: Warn ) , LevelFilter :: Warn ) ,
277
+ ( 3 , 0 , Some ( Level :: Info ) , LevelFilter :: Info ) ,
278
+ ( 4 , 0 , Some ( Level :: Debug ) , LevelFilter :: Debug ) ,
279
+ ( 5 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
280
+ ( 6 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
281
+ ( 255 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
282
+ ( 0 , 1 , None , LevelFilter :: Off ) ,
283
+ ( 0 , 255 , None , LevelFilter :: Off ) ,
284
+ ( 255 , 255 , None , LevelFilter :: Off ) ,
285
+ ] ;
286
+
287
+ for ( verbose, quiet, expected_level, expected_filter) in tests. iter ( ) {
288
+ let v = Verbosity :: < OffLevel > :: new ( * verbose, * quiet) ;
289
+ assert_eq ! (
290
+ v. log_level( ) ,
291
+ * expected_level,
292
+ "verbose = {verbose}, quiet = {quiet}"
293
+ ) ;
294
+ assert_eq ! (
295
+ v. log_level_filter( ) ,
296
+ * expected_filter,
297
+ "verbose = {verbose}, quiet = {quiet}"
298
+ ) ;
299
+ }
300
+ }
301
+
241
302
#[ test]
242
303
fn verbosity_error_level ( ) {
243
304
let tests = [
@@ -333,4 +394,68 @@ mod test {
333
394
) ;
334
395
}
335
396
}
397
+
398
+ #[ test]
399
+ fn verbosity_debug_level ( ) {
400
+ let tests = [
401
+ // verbose, quiet, expected_level, expected_filter
402
+ ( 0 , 0 , Some ( Level :: Debug ) , LevelFilter :: Debug ) ,
403
+ ( 1 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
404
+ ( 2 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
405
+ ( 255 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
406
+ ( 0 , 1 , Some ( Level :: Info ) , LevelFilter :: Info ) ,
407
+ ( 0 , 2 , Some ( Level :: Warn ) , LevelFilter :: Warn ) ,
408
+ ( 0 , 3 , Some ( Level :: Error ) , LevelFilter :: Error ) ,
409
+ ( 0 , 4 , None , LevelFilter :: Off ) ,
410
+ ( 0 , 5 , None , LevelFilter :: Off ) ,
411
+ ( 0 , 255 , None , LevelFilter :: Off ) ,
412
+ ( 255 , 255 , Some ( Level :: Debug ) , LevelFilter :: Debug ) ,
413
+ ] ;
414
+
415
+ for ( verbose, quiet, expected_level, expected_filter) in tests. iter ( ) {
416
+ let v = Verbosity :: < DebugLevel > :: new ( * verbose, * quiet) ;
417
+ assert_eq ! (
418
+ v. log_level( ) ,
419
+ * expected_level,
420
+ "verbose = {verbose}, quiet = {quiet}"
421
+ ) ;
422
+ assert_eq ! (
423
+ v. log_level_filter( ) ,
424
+ * expected_filter,
425
+ "verbose = {verbose}, quiet = {quiet}"
426
+ ) ;
427
+ }
428
+ }
429
+
430
+ #[ test]
431
+ fn verbosity_trace_level ( ) {
432
+ let tests = [
433
+ // verbose, quiet, expected_level, expected_filter
434
+ ( 0 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
435
+ ( 1 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
436
+ ( 255 , 0 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
437
+ ( 0 , 1 , Some ( Level :: Debug ) , LevelFilter :: Debug ) ,
438
+ ( 0 , 2 , Some ( Level :: Info ) , LevelFilter :: Info ) ,
439
+ ( 0 , 3 , Some ( Level :: Warn ) , LevelFilter :: Warn ) ,
440
+ ( 0 , 4 , Some ( Level :: Error ) , LevelFilter :: Error ) ,
441
+ ( 0 , 5 , None , LevelFilter :: Off ) ,
442
+ ( 0 , 6 , None , LevelFilter :: Off ) ,
443
+ ( 0 , 255 , None , LevelFilter :: Off ) ,
444
+ ( 255 , 255 , Some ( Level :: Trace ) , LevelFilter :: Trace ) ,
445
+ ] ;
446
+
447
+ for ( verbose, quiet, expected_level, expected_filter) in tests. iter ( ) {
448
+ let v = Verbosity :: < TraceLevel > :: new ( * verbose, * quiet) ;
449
+ assert_eq ! (
450
+ v. log_level( ) ,
451
+ * expected_level,
452
+ "verbose = {verbose}, quiet = {quiet}"
453
+ ) ;
454
+ assert_eq ! (
455
+ v. log_level_filter( ) ,
456
+ * expected_filter,
457
+ "verbose = {verbose}, quiet = {quiet}"
458
+ ) ;
459
+ }
460
+ }
336
461
}
0 commit comments