feat(app): support different display types for parameters

This commit is contained in:
Orhun Parmaksız 2021-11-22 16:59:55 +03:00
parent 0974e87cf2
commit 7e0a1e0884
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
6 changed files with 83 additions and 14 deletions

View file

@ -1,3 +1,4 @@
use crate::display::DisplayType;
use crate::sysctl::Section;
use colored::Color;
use std::collections::HashMap;
@ -14,10 +15,10 @@ macro_rules! map {
/// General configuration.
#[derive(Debug, Default)]
pub struct Config {
/// Application configuration.
pub app: AppConfig,
/// Sysctl configuration.
pub sysctl: SysctlConfig,
/// Application configuration.
pub color: AppConfig,
}
/// Sysctl configuration.
@ -36,6 +37,8 @@ pub struct AppConfig {
pub section_colors: HashMap<Section, Color>,
/// Default color for the output
pub default_color: Color,
/// Display type of the kernel parameters.
pub display_type: DisplayType,
}
impl Default for AppConfig {
@ -53,6 +56,7 @@ impl Default for AppConfig {
Section::Unknown => Color::BrightBlack
},
default_color: Color::BrightBlack,
display_type: DisplayType::default(),
}
}
}

View file

@ -0,0 +1,18 @@
/// Possible ways of displaying the kernel variables.
#[derive(Debug)]
pub enum DisplayType {
/// Print the kernel variable name along with its value.
Default,
/// Print only the name of the variable.
Name,
/// Print only the value of the variable.
Value,
/// Print only the value of the variable without new line.
Binary,
}
impl Default for DisplayType {
fn default() -> Self {
Self::Default
}
}

View file

@ -16,3 +16,6 @@ pub mod parsers;
/// Configuration.
pub mod config;
/// Display options.
pub mod display;

View file

@ -1,4 +1,5 @@
use crate::config::{AppConfig, SysctlConfig};
use crate::display::DisplayType;
use crate::error::Result;
use crate::parsers::parse_kernel_docs;
use colored::*;
@ -119,15 +120,41 @@ impl Parameter {
/// Prints the kernel parameter to given output.
pub fn display_value<W: Write>(&self, config: &AppConfig, output: &mut W) -> Result<()> {
if !config.no_color {
writeln!(
output,
"{} {} {}",
self.colored_name(config),
"=".color(config.default_color),
self.value.bold(),
)?;
match config.display_type {
DisplayType::Name => {
writeln!(output, "{}", self.colored_name(config))?;
}
DisplayType::Value => {
writeln!(output, "{}", self.value.bold())?;
}
DisplayType::Binary => {
write!(output, "{}", self.value.bold())?;
}
DisplayType::Default => {
writeln!(
output,
"{} {} {}",
self.colored_name(config),
"=".color(config.default_color),
self.value.bold(),
)?;
}
}
} else {
writeln!(output, "{} = {}", self.name, self.value)?;
match config.display_type {
DisplayType::Name => {
writeln!(output, "{}", self.name)?;
}
DisplayType::Value => {
writeln!(output, "{}", self.value)?;
}
DisplayType::Binary => {
write!(output, "{}", self.value)?;
}
DisplayType::Default => {
writeln!(output, "{} = {}", self.name, self.value)?;
}
}
}
Ok(())
}

View file

@ -1,6 +1,7 @@
use getopts::Options;
use std::env;
use std::path::PathBuf;
use systeroid_core::display::DisplayType;
/// Help message for the arguments.
const HELP_MESSAGE: &str = r#"
@ -17,6 +18,8 @@ For more details see {bin}(8)."#;
pub struct Args {
/// Path of the Linux kernel documentation.
pub kernel_docs: PathBuf,
/// Display type of the variables.
pub display_type: DisplayType,
/// Whether if the unknown variable errors should be ignored.
pub ignore_errors: bool,
/// Parameter to explain.
@ -29,12 +32,13 @@ impl Args {
/// Parses the command-line arguments.
pub fn parse() -> Option<Self> {
let mut opts = Options::new();
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
opts.optflag("a", "all", "display all variables");
opts.optflag("A", "", "alias of -a");
opts.optflag("X", "", "alias of -a");
opts.optflag("b", "binary", "print value without new line");
opts.optflag("e", "ignore", "ignore unknown variables errors");
opts.optflag("N", "names", "print variable names without values");
opts.optflag("n", "values", "print only values of the given variable(s)");
opts.optopt(
"",
"explain",
@ -47,6 +51,8 @@ impl Args {
"set the path of the kernel documentation\n(default: /usr/share/doc/linux/)",
"<path>",
);
opts.optflag("h", "help", "display this help and exit");
opts.optflag("V", "version", "output version information and exit");
let matches = opts
.parse(&env::args().collect::<Vec<String>>()[1..])
@ -71,12 +77,22 @@ impl Args {
println!("{} {}", env!("CARGO_PKG_NAME"), env!("CARGO_PKG_VERSION"));
None
} else {
let display_type = if matches.opt_present("N") {
DisplayType::Name
} else if matches.opt_present("n") {
DisplayType::Value
} else if matches.opt_present("b") {
DisplayType::Binary
} else {
DisplayType::Default
};
Some(Args {
kernel_docs: PathBuf::from(
matches
.opt_str("d")
.unwrap_or_else(|| String::from("/usr/share/doc/linux/")),
),
display_type,
ignore_errors: matches.opt_present("e"),
param_to_explain: matches.opt_str("explain"),
param_names: matches.free,

View file

@ -18,9 +18,10 @@ use systeroid_core::sysctl::Sysctl;
pub fn run(args: Args) -> Result<()> {
let mut config = Config::default();
config.sysctl.ignore_errors = args.ignore_errors;
config.color.no_color = env::var("NO_COLOR").is_ok();
config.app.display_type = args.display_type;
config.app.no_color = env::var("NO_COLOR").is_ok();
let mut sysctl = Sysctl::init(config.sysctl)?;
let mut app = App::new(&mut sysctl, &config.color);
let mut app = App::new(&mut sysctl, &config.app);
if let Some(param) = args.param_to_explain {
app.display_documentation(&param, &args.kernel_docs)?;