1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
//! # Printting and Command Line Interface
//!
//! There are 4 feature flags related to CLI
//! - `print`: This is the most minimal feature set. Using
//! features from this feature flag means you acknowledge your code
//! is being called from a program that uses `cu::cli` (i.e. the `cli` feature)
//! - `cli`: Use this if your crate is the end binary (i.e. not a library).
//! This integrates and re-exports [`clap`](https://docs.rs/clap).
//! - This turns on `print` automatically
//! - `prompt`: This implies `print` and will also enable the ability to show prompts in the terminal,
//! including password prompts (which hide the input when user types into the terminal).
//!
//! # Integration with `clap`
//!
//! When the `cli` feature is enabled, `clap` is re-exported from the prelude,
//! so you can use `clap` as if it's a dependency, without actually adding
//! it to your `Cargo.toml`
//! ```rust,no_run
//! # use pistonite_cu as cu;
//! use cu::pre::*;
//! use clap::Parser;
//!
//! #[derive(Parser)]
//! struct MyCli {
//! /// Just an example flag
//! #[clap(short, long)]
//! hello: bool,
//! }
//! ```
//!
//! # Common Command Options
//! The [`Flags`] struct implement `clap::Args` to provide common
//! options that integrates with the rest of the crate:
//! - `--verbose`/`-v` to increase verbose level.
//! - `--quiet`/`-q` to decrease verbose level.
//! - `--color` to set color mode
//!
//! The `prompt` feature enables these additional options:
//! - `--yes`/`-y` to answer `y` to all yes/no prompts.
//! - `--non-interactive`: Disallow prompts, prompts will fail with an error instead
//! - With `--yes --non-interactive`, yes/no prompts gets answered `yes` and other prompts are
//! blocked
//! - `--interactive`: This is the default, and cancels the effect of one `--non-interactive`
//!
//! The [`cu::cli`](macro@crate::cli) macro generates a shim
//! to parse the flags and pass it to your main function.
//! It also handles the `Result` returned back. See the example
//! below and more usage examples in the documentation for the macro.
//! ```rust,no_run
//! # use pistonite_cu as cu;
//! use cu::pre::*;
//! // clap will be part of the prelude
//! // when the `cli` feature is enabled
//!
//! // Typically, you want to have a wrapper struct
//! // so you can derive additional options with clap,
//! // and provide a description via doc comments, like below
//!
//! // clap will parse the doc comment of the Args struct
//! // as the help text
//!
//! /// My program
//! ///
//! /// This is my program, it is very good.
//! #[derive(clap::Parser, Clone)]
//! struct Args {
//! /// Input of the program
//! #[clap(short, long)]
//! input: String,
//! /// Output of the program
//! #[clap(short, long)]
//! output: Option<String>,
//! #[clap(flatten)]
//! inner: cu::cli::Flags,
//! }
//! // use the flags attribute to refer to the cu::cli::Flags field inside the Args struct
//! #[cu::cli(flags = "inner")]
//! fn main(args: Args) -> cu::Result<()> {
//! cu::info!("input is {}", args.input);
//! cu::info!("output is {:?}", args.output);
//! Ok(())
//! }
//! ```
//!
//! # Printing and Logging
//! In addition to the logging macros re-exported from the [`log`](https://docs.rs/log)
//! crate, `cu` provides `print` and `hint` macros:
//! - `print`: like `info`, but has a higher importance
//! - `hint`: like `print`, but specifically for hinting actions the user can take
//! (to resolve an error, for example).
//!
//! These 2 levels are not directly controlled by `log`,
//! and can still print when logging is statically disabled.
//!
//! The following table shows what are printed for each level,
//! | | `-qq` | ` -q` | ` ` | ` -v` | `-vv` |
//! |-|- |- |- |- |- |
//! | [`error!`](crate::error) | ❌ | ✅ | ✅ | ✅ | ✅ |
//! | [`hint!`](crate::hint) | ❌ | ✅ | ✅ | ✅ | ✅ |
//! | [`print!`](macro@crate::print) | ❌ | ✅ | ✅ | ✅ | ✅ |
//! | [`warn!`](crate::warn) | ❌ | ❌ | ✅ | ✅ | ✅ |
//! | [`info!`](crate::info) | ❌ | ❌ | ✅ | ✅ | ✅ |
//! | [`debug!`](crate::debug) | ❌ | ❌ | ❌ | ✅ | ✅ |
//! | [`trace!`](crate::trace) | ❌ | ❌ | ❌ | ❌ | ✅ |
//!
//! The `RUST_LOG` environment variable is also supported in the same
//! way as in [`env_logger`](https://docs.rs/env_logger/latest/env_logger/#enabling-logging).
//! When mixing `RUST_LOG` and verbosity flags, logging messages are filtered
//! by `RUST_LOG`, and the verbosity would only apply to `print` and `hint`
//!
//! # Other
//! When setting up test, you can use [`cu::cli::level`] to quickly inititialize logging
//! without dealing with the details.
//!
//! [`cu::cli::set_thread_name`] can be used to add a prefix to all messages printed
//! by the current thread.
//!
//! Messages that are too long and multi-line messages are automatically wrapped.
//!
//! # Manual Parsing CLI args
//! [`cu::cli::try_parse`](crate::cli::try_parse)
//! and [`cu::cli::print_help`](crate::cli::print_help) can be useful
//! when you want to manually invoke a command parser. These
//! respect the `--color` option passed to the program.
//!
//! # Ctrl-C Signals
//! We wrap the [`ctrlc`](https://docs.rs/ctrlc) crate because it only allows
//! for one global handler. See [Handling Ctrl-C](fn@crate::cli::ctrlc_frame)
//!
//! # Progress Bars
//! See [Progress Bars](fn@crate::progress)
//!
//! # Prompting
//! See [Prompting](fn@crate::prompt)
//!
pub use __co_run;
pub use ;
pub use ;
pub use __print_with_level;
use THREAD_NAME;
pub use ;
pub use ;
pub use ;
pub use password_chars_legal;
pub use add_global_ctrlc_handler;
pub use ;
/// Formatting utils
pub
// 50ms between each cycle
const TICK_INTERVAL: Duration = from_millis;
// 2B ticks * 10ms = 251 days.
// overflown tick means ETA will be inaccurate (after 251 days)
type Tick = u32;