libaki_mcycle/
lib.rs

1/*!
2the mark up text with cycling color program.
3
4# Features
5
6- mark up text with cycling color.
7- minimum support rustc 1.65.0 (897e37553 2022-11-02)
8
9# Command help
10
11```text
12aki-mcycle --help
13```
14
15```text
16Usage:
17  aki-mcycle [options]
18
19mark up text with the cyclic color.
20
21Options:
22  -e, --exp <exp>   write it in the cyclic color (default: ' ([0-9A-Z]{3,}):')
23
24  -H, --help        display this help and exit
25  -V, --version     display version information and exit
26
27Option Parameters:
28  <exp>     regular expression, color the entire match with the cyclic color.
29
30Environments:
31  AKI_MCYCLE_COLOR_SEQ_RED_ST       red start sequence specified by ansi
32  AKI_MCYCLE_COLOR_SEQ_GREEN_ST     green start sequence specified by ansi
33  AKI_MCYCLE_COLOR_SEQ_BLUE_ST      blue start sequence specified by ansi
34  AKI_MCYCLE_COLOR_SEQ_CYAN_ST      cyan start sequence specified by ansi
35  AKI_MCYCLE_COLOR_SEQ_MAGENDA_ST   magenda start sequence specified by ansi
36  AKI_MCYCLE_COLOR_SEQ_YELLOW_ST    yellow start sequence specified by ansi
37  AKI_MCYCLE_COLOR_SEQ_ED           color end sequence specified by ansi
38```
39
40# Quick install
41
421. you can install this into cargo bin path:
43
44```text
45cargo install aki-mcycle
46```
47
482. you can build debian package:
49
50```text
51cargo deb
52```
53
54and install **.deb** into your local repository of debian package.
55
56# Examples
57
58## Command line example 1
59
60Extract "`arm`" from the rustup target list and make "`linux-[^ ]+`" **color**.
61
62- 1st match: makes '`linux-musl`' **red**
63- 2nd match: makes '`linux-musleabi`' **green**
64- 3rd match: makes '`linux-musleabihf`' **blue**
65- 4th match: makes '`linux-muslabi64`' **cyan**
66
67```text
68rustup target list | aki-mline -e arm | aki-mcycle -e "linux-[^ ]+"
69```
70
71result output :
72
73![out rustup image]
74
75[out rustup image]: https://raw.githubusercontent.com/aki-akaguma/aki-mcycle/main/img/out-rustup-1.png
76
77- [aki-mline](https://crates.io/crates/aki-mline): extract match line command like grep.
78
79# Library example
80
81See [`fn execute()`] for this library examples.
82
83[`fn execute()`]: crate::execute
84
85*/
86#[macro_use]
87extern crate anyhow;
88
89pub mod conf;
90mod run;
91mod util;
92
93use flood_tide::HelpVersion;
94use runnel::*;
95
96const TRY_HELP_MSG: &str = "Try --help for help.";
97
98///
99/// execute mcycle
100///
101/// params:
102///   - sioe: stream in/out/err
103///   - program: program name. etc. "mcycle"
104///   - args: parameter arguments.
105///
106/// return:
107///   - ok: ()
108///   - err: anyhow
109///
110/// example:
111///
112/// ```
113/// use runnel::RunnelIoeBuilder;
114///
115/// let r = libaki_mcycle::execute(&RunnelIoeBuilder::new().build(),
116///     "mcycle", ["-e", "Message: *[^ ]+"]);
117/// ```
118///
119pub fn execute<I, S>(sioe: &RunnelIoe, prog_name: &str, args: I) -> anyhow::Result<()>
120where
121    I: IntoIterator<Item = S>,
122    S: AsRef<std::ffi::OsStr>,
123{
124    execute_with_env(sioe, prog_name, args, vec![("", "")])
125}
126
127///
128/// execute mcycle with environments
129///
130/// params:
131///   - sioe: stream in/out/err
132///   - program: program name. etc. "mcycle"
133///   - args: parameter arguments.
134///   - env: environments array.
135///
136/// return:
137///   - ok: ()
138///   - err: anyhow
139///
140/// example:
141///
142/// ```rust
143/// use runnel::RunnelIoeBuilder;
144///
145/// let r = libaki_mcycle::execute_with_env(&RunnelIoeBuilder::new().build(),
146///     "mcycle",
147///     ["-e", "Message: *[^ ]+"],
148///     vec![
149///         ("AKI_MCYCLE_COLOR_SEQ_RED_ST", "<R>"),
150///         ("AKI_MCYCLE_COLOR_SEQ_GREEN_ST", "<G>"),
151///         ("AKI_MCYCLE_COLOR_SEQ_BLUE_ST", "<B>"),
152///         ("AKI_MCYCLE_COLOR_SEQ_CYAN_ST", "<C>"),
153///         ("AKI_MCYCLE_COLOR_SEQ_MAGENDA_ST", "<M>"),
154///         ("AKI_MCYCLE_COLOR_SEQ_YELLOW_ST", "<Y>"),
155///         ("AKI_MCYCLE_COLOR_SEQ_ED","<E>"),
156///     ]
157/// );
158/// ```
159///
160pub fn execute_with_env<I, S, IKV, K, V>(
161    sioe: &RunnelIoe,
162    prog_name: &str,
163    args: I,
164    env: IKV,
165) -> anyhow::Result<()>
166where
167    I: IntoIterator<Item = S>,
168    S: AsRef<std::ffi::OsStr>,
169    IKV: IntoIterator<Item = (K, V)>,
170    K: AsRef<std::ffi::OsStr>,
171    V: AsRef<std::ffi::OsStr>,
172{
173    let args: Vec<String> = args
174        .into_iter()
175        .map(|s| s.as_ref().to_string_lossy().into_owned())
176        .collect();
177    let args_str: Vec<&str> = args.iter().map(|s| s.as_str()).collect();
178    let env_cnf: conf::EnvConf = env.into();
179    //
180    match conf::parse_cmdopts(prog_name, &args_str) {
181        Ok(conf) => run::run(sioe, &conf, &env_cnf),
182        Err(errs) => {
183            if let Some(err) = errs.iter().find(|e| e.is_help() || e.is_version()) {
184                sioe.pg_out().write_line(err.to_string())?;
185                Ok(())
186            } else {
187                Err(anyhow!("{errs}\n{TRY_HELP_MSG}"))
188            }
189        }
190    }
191}