Skip to content
This repository was archived by the owner on Sep 13, 2023. It is now read-only.

Commit 5e49790

Browse files
committed
Introduce a Verbosity type
Add it to your structopt type and you'll get a nice way to init env_logger.
1 parent 3ee8e57 commit 5e49790

File tree

10 files changed

+85
-36
lines changed

10 files changed

+85
-36
lines changed

docs/Readme.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ struct Cli {
7676
// Add a positional argument that the user has to supply:
7777
/// The file to read
7878
file: String,
79-
/// Pass many times for more log output
80-
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
81-
verbosity: u8,
79+
// Quick and easy logging setup you get for free with quicli
80+
#[structopt(flatten)]
81+
verbosity: Verbosity,
8282
}
8383
```
8484

docs/commit.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,8 @@ struct Cli {
7676
/// How many?
7777
#[structopt(long = "amount", default_value = "3")]
7878
amount: i32,
79-
/// Pass many times for more log output
80-
#[structopt(long = "verbosity", short = "v", parse(from_occurrences))]
81-
verbosity: u8,
79+
#[structopt(flatten)]
80+
verbosity: Verbosity,
8281
}
8382
```
8483

docs/thumbnails.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,8 @@ Here we go:
7575
/// Make some thumbnails
7676
#[derive(Debug, StructOpt)]
7777
struct Cli {
78-
/// Pass many times for more log output
79-
#[structopt(long = "verbosity", short = "v", parse(from_occurrences))]
80-
verbosity: u8,
78+
#[structopt(flatten)]
79+
verbosity: Verbosity,
8180
```
8281

8382
So far so typical for a _quicli_ app.

examples/Readme/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ struct Cli {
1111
// Add a positional argument that the user has to supply:
1212
/// The file to read
1313
file: String,
14-
/// Pass many times for more log output
15-
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
16-
verbosity: u8,
14+
// Quick and easy logging setup you get for free with quicli
15+
#[structopt(flatten)]
16+
verbosity: Verbosity,
1717
}
1818
main!(|args: Cli, log_level: verbosity| {
1919
let content = read_file(&args.file)?;

examples/commit/src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ struct Cli {
88
/// How many?
99
#[structopt(long = "amount", default_value = "3")]
1010
amount: i32,
11-
/// Pass many times for more log output
12-
#[structopt(long = "verbosity", short = "v", parse(from_occurrences))]
13-
verbosity: u8,
11+
#[structopt(flatten)]
12+
verbosity: Verbosity,
1413
}
1514
#[derive(Deserialize)]
1615
struct Commit {

examples/thumbnails/src/main.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ use quicli::prelude::*;
44
/// Make some thumbnails
55
#[derive(Debug, StructOpt)]
66
struct Cli {
7-
/// Pass many times for more log output
8-
#[structopt(long = "verbosity", short = "v", parse(from_occurrences))]
9-
verbosity: u8,
7+
#[structopt(flatten)]
8+
verbosity: Verbosity,
109
/// Which files?
1110
#[structopt(default_value = "*.jpg")]
1211
pattern: String,

examples/verbosity/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use quicli::prelude::*;
55
/// Verbosity by any other name is still as verbose
66
#[derive(Debug, StructOpt)]
77
struct Cli {
8-
#[structopt(long = "verbose", short = "v", parse(from_occurrences))]
9-
team_rockets_blasting_off_again: u8,
8+
#[structopt(flatten)]
9+
team_rockets_blasting_off_again: Verbosity,
1010
}
1111

1212
main!(|cli_args: Cli, log_level: team_rockets_blasting_off_again| {

src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ extern crate rayon;
3131
#[cfg(feature = "full-throttle")]
3232
pub mod fs;
3333
mod main_macro;
34+
mod log_level;
3435

3536
mod reexports {
3637
#[cfg(feature = "full-throttle")]
@@ -74,8 +75,5 @@ pub mod prelude {
7475
#[cfg(feature = "full-throttle")]
7576
pub use fs::*;
7677

77-
#[doc(hidden)]
78-
pub use env_logger::Builder as LoggerBuilder;
79-
#[doc(hidden)]
80-
pub use log::Level as LogLevel;
78+
pub use log_level::Verbosity;
8179
}

src/log_level.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#![allow(missing_docs)]
2+
3+
use log::{Level, LevelFilter};
4+
use env_logger::Builder as LoggerBuilder;
5+
use failure::Error;
6+
7+
/// Easily add a `--verbose` flag to CLIs using Structopt
8+
///
9+
/// # Examples
10+
///
11+
/// ```rust
12+
/// extern crate quicli;
13+
/// #[macro_use] extern crate structopt;
14+
///
15+
/// use structopt::StructOpt;
16+
/// use quicli::prelude::Verbosity;
17+
///
18+
/// /// Le CLI
19+
/// #[derive(Debug, StructOpt)]
20+
/// struct Cli {
21+
/// #[structopt(flatten)]
22+
/// verbose: Verbosity,
23+
/// }
24+
/// #
25+
/// # fn main() {}
26+
/// ```
27+
#[derive(StructOpt, Debug)]
28+
pub struct Verbosity {
29+
/// Pass many times for more log output
30+
///
31+
/// By default, it'll only report errors. Passing `-v` one time also prints
32+
/// warnings, `-vv` enables info logging, `-vvv` debug, and `-vvvv` trace.
33+
#[structopt(long = "verbosity", short = "v", parse(from_occurrences))]
34+
verbosity: u8,
35+
}
36+
37+
impl Verbosity {
38+
fn log_level(&self) -> LevelFilter {
39+
match self.verbosity {
40+
0 => Level::Error,
41+
1 => Level::Warn,
42+
2 => Level::Info,
43+
3 => Level::Debug,
44+
_ => Level::Trace,
45+
}.to_level_filter()
46+
}
47+
48+
/// Initialize `env_logger` and set the log level for the given package.
49+
///
50+
/// All other modules default to printing warnings.
51+
pub fn setup_env_logger(&self, own_pkg_name: &str) -> Result<(), Error> {
52+
LoggerBuilder::new()
53+
.filter(Some(&own_pkg_name.replace("-", "_")), self.log_level())
54+
.filter(None, Level::Warn.to_level_filter())
55+
.try_init()?;
56+
Ok(())
57+
}
58+
}
59+
60+
use std::fmt;
61+
62+
impl fmt::Display for Verbosity {
63+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64+
write!(f, "{}", self.verbosity)
65+
}
66+
}

src/main_macro.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,7 @@ macro_rules! main {
3535
fn main() {
3636
fn run() -> $crate::prelude::Result<()> {
3737
let $args = <$cli>::from_args();
38-
let log_level = match $args.$verbosity {
39-
0 => $crate::prelude::LogLevel::Error,
40-
1 => $crate::prelude::LogLevel::Warn,
41-
2 => $crate::prelude::LogLevel::Info,
42-
3 => $crate::prelude::LogLevel::Debug,
43-
_ => $crate::prelude::LogLevel::Trace,
44-
}.to_level_filter();
45-
46-
$crate::prelude::LoggerBuilder::new()
47-
.filter(Some(&env!("CARGO_PKG_NAME").replace("-", "_")), log_level)
48-
.filter(None, $crate::prelude::LogLevel::Warn.to_level_filter())
49-
.try_init()?;
38+
$args.$verbosity.setup_env_logger(&env!("CARGO_PKG_NAME"))?;
5039

5140
$body
5241

0 commit comments

Comments
 (0)