refactor(app): create application controller

This commit is contained in:
Orhun Parmaksız 2021-11-10 23:08:21 +03:00
parent ad024dc5c2
commit 4a22e7cc63
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
2 changed files with 78 additions and 37 deletions

70
systeroid/src/app.rs Normal file
View file

@ -0,0 +1,70 @@
use std::io::{self, Stdout};
use systeroid_core::config::Config;
use systeroid_core::error::Result;
use systeroid_core::sysctl::Sysctl;
/// Application controller.
#[derive(Debug)]
pub struct App<'a> {
/// Sysctl manager.
sysctl: &'a mut Sysctl,
/// Configuration.
config: &'a Config,
/// Standard output.
stdout: Stdout,
}
impl<'a> App<'a> {
/// Constructs a new instance.
pub fn new(sysctl: &'a mut Sysctl, config: &'a Config) -> Self {
let stdout = io::stdout();
Self {
sysctl,
config,
stdout,
}
}
/// Displays all of the available kernel modules.
pub fn display_parameters(&mut self) -> Result<()> {
self.sysctl
.parameters
.iter()
.try_for_each(|parameter| parameter.display(&self.config.color, &mut self.stdout))
}
/// Updates the parameter if it has the format `name=value`, displays it otherwise.
pub fn process_parameter(&mut self, mut param_name: String) -> Result<()> {
let new_value = if param_name.contains('=') {
let fields = param_name
.split('=')
.take(2)
.map(String::from)
.collect::<Vec<String>>();
param_name = fields[0].to_string();
Some(fields[1].to_string())
} else {
None
};
match self
.sysctl
.parameters
.iter_mut()
.find(|param| param.name == *param_name)
{
Some(parameter) => {
if let Some(new_value) = new_value {
parameter.update(&new_value, &self.config.color, &mut self.stdout)?;
} else {
parameter.display(&self.config.color, &mut self.stdout)?;
}
}
None => eprintln!(
"{}: cannot stat /proc/{}: No such file or directory",
env!("CARGO_PKG_NAME"),
param_name.replace(".", "/")
),
}
Ok(())
}
}

View file

@ -2,11 +2,13 @@
#![warn(missing_docs, clippy::unwrap_used)]
/// Main application.
pub mod app;
/// Command-line argument parser.
pub mod args;
use crate::app::App;
use crate::args::Args;
use std::io::{self, Write};
use systeroid_core::config::Config;
use systeroid_core::error::Result;
use systeroid_core::sysctl::Sysctl;
@ -15,50 +17,19 @@ use systeroid_core::sysctl::Sysctl;
pub fn run(args: Args) -> Result<()> {
let mut config = Config::default();
config.color.no_color = args.no_color;
let (mut stdout, mut stderr) = (io::stdout(), io::stderr());
let mut sysctl = Sysctl::init()?;
if let Some(kernel_docs) = args.kernel_docs {
sysctl.update_docs(&kernel_docs)?;
}
let mut app = App::new(&mut sysctl, &config);
if args.param_names.is_empty() {
sysctl
.parameters
.iter()
.try_for_each(|parameter| parameter.display(&config.color, &mut stdout))?;
app.display_parameters()?;
} else {
for mut param_name in args.param_names {
let new_value = if param_name.contains('=') {
let fields = param_name
.split('=')
.take(2)
.map(String::from)
.collect::<Vec<String>>();
param_name = fields[0].to_string();
Some(fields[1].to_string())
} else {
None
};
match sysctl
.parameters
.iter_mut()
.find(|param| param.name == *param_name)
{
Some(parameter) => {
if let Some(new_value) = new_value {
parameter.update(&new_value, &config.color, &mut stdout)?;
} else {
parameter.display(&config.color, &mut stdout)?;
}
}
None => writeln!(
stderr,
"{}: cannot stat /proc/{}: No such file or directory",
env!("CARGO_PKG_NAME"),
param_name.replace(".", "/")
)?,
}
for param_name in args.param_names {
app.process_parameter(param_name)?;
}
}