feat(app): support tree format for all cases

This commit is contained in:
Orhun Parmaksız 2021-12-17 21:04:11 +03:00
parent 3f0286fb59
commit d26bbf6093
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
5 changed files with 43 additions and 32 deletions

View file

@ -10,7 +10,7 @@ use std::result::Result as StdResult;
use sysctl::{CtlFlags, CtlIter, Sysctl as SysctlImpl};
/// Sysctl wrapper for managing the kernel parameters.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct Sysctl {
/// Available kernel parameters.
pub parameters: Vec<Parameter>,

View file

@ -9,7 +9,7 @@ use std::path::PathBuf;
use sysctl::{Ctl, Sysctl as SysctlImpl};
/// Representation of a kernel parameter.
#[derive(Serialize, Deserialize, Debug)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Parameter {
/// Name of the kernel parameter.
pub name: String,

View file

@ -20,7 +20,10 @@ pub struct TreeNode {
impl TreeNode {
/// Adds new child nodes to the tree node.
pub fn add<'a, I: Iterator<Item = &'a str>>(&mut self, values: &mut I) {
pub fn add<'a, I>(&mut self, values: &mut I)
where
I: Iterator<Item = &'a str>,
{
if let Some(value) = values.next() {
let mut found = false;
for child in self.childs.iter_mut() {

View file

@ -7,6 +7,7 @@ use systeroid_core::error::Result;
use systeroid_core::parsers::KERNEL_DOCS_PATH;
use systeroid_core::regex::Regex;
use systeroid_core::sysctl::controller::Sysctl;
use systeroid_core::sysctl::parameter::Parameter;
use systeroid_core::sysctl::{DEPRECATED_PARAMS, SYSTEM_PRELOAD};
use systeroid_core::tree::{Tree, TreeNode};
use systeroid_parser::globwalk;
@ -22,39 +23,29 @@ pub struct App<'a> {
sysctl: &'a mut Sysctl,
/// Application cache.
cache: Cache,
/// Whether if the output will be in tree format.
tree_output: bool,
/// Standard output.
stdout: Stdout,
}
impl<'a> App<'a> {
/// Constructs a new instance.
pub fn new(sysctl: &'a mut Sysctl) -> Result<Self> {
pub fn new(sysctl: &'a mut Sysctl, tree_output: bool) -> Result<Self> {
Ok(Self {
sysctl,
cache: Cache::init()?,
tree_output,
stdout: io::stdout(),
})
}
/// Displays all of the available kernel parameters.
pub fn display_parameters(
&mut self,
pattern: Option<Regex>,
display_deprecated: bool,
tree_output: bool,
) -> Result<()> {
let mut parameters = self.sysctl.parameters.iter().filter(|parameter| {
if let Some(pattern) = &pattern {
return pattern.is_match(&parameter.name);
}
if !display_deprecated {
if let Some(param_name) = parameter.absolute_name() {
return !DEPRECATED_PARAMS.contains(&param_name);
}
}
true
});
if tree_output {
/// Prints the given parameters to stdout.
fn print_parameters<'b, I>(&mut self, parameters: &mut I) -> Result<()>
where
I: Iterator<Item = &'b Parameter>,
{
if self.tree_output {
let mut root_node = TreeNode::default();
parameters.for_each(|parameter| {
root_node.add(
@ -74,6 +65,27 @@ impl<'a> App<'a> {
Ok(())
}
/// Displays all of the available kernel parameters.
pub fn display_parameters(
&mut self,
pattern: Option<Regex>,
display_deprecated: bool,
) -> Result<()> {
let parameters = self.sysctl.parameters.clone();
let mut parameters = parameters.iter().filter(|parameter| {
if let Some(pattern) = &pattern {
return pattern.is_match(&parameter.name);
}
if !display_deprecated {
if let Some(param_name) = parameter.absolute_name() {
return !DEPRECATED_PARAMS.contains(&param_name);
}
}
true
});
self.print_parameters(&mut parameters)
}
/// Updates the documentation for kernel parameters.
pub fn update_documentation(&mut self, kernel_docs: Option<&PathBuf>) -> Result<()> {
let mut kernel_docs_path = KERNEL_DOCS_PATH.clone();
@ -169,12 +181,9 @@ impl<'a> App<'a> {
parameter
);
} else if display_value {
self.sysctl
.get_parameters(&parameter)
.iter()
.try_for_each(|parameter| {
parameter.display_value(&self.sysctl.config, &mut self.stdout)
})?;
let sysctl = self.sysctl.clone();
let parameters = sysctl.get_parameters(&parameter);
self.print_parameters(&mut parameters.into_iter())?;
}
Ok(())
}
@ -216,7 +225,6 @@ impl<'a> App<'a> {
}
}
}
Ok(())
}
}

View file

@ -24,12 +24,12 @@ pub fn run(args: Args) -> Result<()> {
..Default::default()
};
let mut sysctl = Sysctl::init(config)?;
let mut app = App::new(&mut sysctl)?;
let mut app = App::new(&mut sysctl, args.tree_output)?;
if args.preload_system_files {
app.preload_from_system()?;
} else if args.values.is_empty() {
app.display_parameters(args.pattern, args.display_deprecated, args.tree_output)?;
app.display_parameters(args.pattern, args.display_deprecated)?;
} else if args.explain {
app.update_documentation(args.kernel_docs.as_ref())?;
for param in args.values {