Skip to content

Commit 5f5565c

Browse files
committed
refactor(lib): orchestrate config loading, engine creation, and frontend dispatch
run() now accepts parsed CLI args, loads config (or defaults with --no-config), resolves module list from CLI flags or config defaults, creates an Engine, and dispatches to either print-once, watch loop, or TUI based on the subcommand. Watch mode enables raw terminal mode for clean q-to-quit behavior and restores it on exit.
1 parent ac81b00 commit 5f5565c

1 file changed

Lines changed: 79 additions & 44 deletions

File tree

src/lib.rs

Lines changed: 79 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,92 @@
11
pub mod cli;
2+
pub mod config;
23
pub mod core;
4+
pub mod engine;
5+
pub mod error;
36
pub mod modules;
47
pub mod output;
58
pub mod tui;
69

7-
use crate::core::MetricCollector;
8-
use crate::modules::disk::DiskCollector;
9-
use crate::modules::{cpu::CpuCollector, memory::MemoryCollector};
10-
use crate::output::{OutputFormat, format_output};
11-
12-
pub fn run() {
13-
let args = cli::parse_args();
14-
15-
// get list of collectors based on args
16-
let collectors: Vec<Box<dyn MetricCollector>> = match args.module.as_deref() {
17-
Some("cpu") => vec![Box::new(CpuCollector::new())],
18-
Some("memory") => vec![Box::new(MemoryCollector::new())],
19-
Some("disk") => vec![Box::new(DiskCollector::new())],
20-
Some(_) => {
21-
eprintln!("Unknown module: {}", args.module.unwrap());
22-
std::process::exit(1);
23-
}
24-
None => {
25-
vec![
26-
Box::new(CpuCollector::new()),
27-
Box::new(MemoryCollector::new()),
28-
Box::new(DiskCollector::new()), // default me disk bhi add
29-
]
30-
}
31-
};
10+
use crate::cli::{Cli, Command};
11+
use crate::config::load_config;
12+
use crate::engine::Engine;
13+
use crate::error::Result;
14+
use crate::output::{format_snapshot, OutputFormat};
3215

16+
pub fn run(args: Cli) -> Result<()> {
17+
let config = if args.no_config {
18+
config::Config::default()
19+
} else {
20+
load_config(args.config.as_deref())?
21+
};
3322

34-
// determine output format
35-
let format = match args.output.as_deref() {
36-
Some("json") => OutputFormat::Json,
37-
Some("table") => OutputFormat::Table,
38-
Some("raw") => OutputFormat::Raw,
39-
Some(_) => {
40-
eprintln!("Unknown output format: {}", args.output.unwrap());
41-
std::process::exit(1);
23+
match args.command {
24+
Some(Command::Tui { module }) => {
25+
let modules = resolve_modules(module, &config);
26+
let engine = Engine::new(&modules)?;
27+
tui::run_tui(engine, config)
4228
}
43-
None => OutputFormat::Table,
44-
};
29+
Some(Command::Print {
30+
module,
31+
output,
32+
watch,
33+
}) => {
34+
let modules = resolve_modules(module, &config);
35+
let engine = Engine::new(&modules)?;
36+
let format = match output {
37+
Some(fmt) => OutputFormat::from(fmt),
38+
None => OutputFormat::from_str_lossy(&config.print.output),
39+
};
4540

46-
// collect and display metrics
47-
for collector in collectors {
48-
match collector.collect() {
49-
Ok(data) => {
50-
println!("=== {} Metrics ===", collector.name());
51-
println!("{}", format_output(&data, format.clone()));
52-
println!();
41+
if watch || config.print.watch {
42+
run_watch(engine, format, config.general.refresh_ms)
43+
} else {
44+
run_print_once(engine, format)
5345
}
54-
Err(e) => eprintln!("Error collecting {} metrics: {}", collector.name(), e),
46+
}
47+
None => {
48+
let modules = resolve_modules(None, &config);
49+
let engine = Engine::new(&modules)?;
50+
let format = OutputFormat::from_str_lossy(&config.print.output);
51+
run_print_once(engine, format)
5552
}
5653
}
57-
}
54+
}
55+
56+
fn resolve_modules(cli_modules: Option<Vec<String>>, config: &config::Config) -> Vec<String> {
57+
cli_modules.unwrap_or_else(|| config.general.default_modules.clone())
58+
}
59+
60+
fn run_print_once(engine: Engine, format: OutputFormat) -> Result<()> {
61+
let snapshot = engine.collect_once();
62+
print!("{}", format_snapshot(&snapshot, &format));
63+
Ok(())
64+
}
65+
66+
fn run_watch(engine: Engine, format: OutputFormat, refresh_ms: u64) -> Result<()> {
67+
let duration = std::time::Duration::from_millis(refresh_ms);
68+
69+
crossterm::terminal::enable_raw_mode()?;
70+
71+
let result = (|| -> Result<()> {
72+
loop {
73+
print!("\x1B[2J\x1B[1;1H");
74+
let snapshot = engine.collect_once();
75+
print!("{}", format_snapshot(&snapshot, &format));
76+
77+
if crossterm::event::poll(duration)? {
78+
if let crossterm::event::Event::Key(key) = crossterm::event::read()? {
79+
if key.code == crossterm::event::KeyCode::Char('q')
80+
|| key.code == crossterm::event::KeyCode::Esc
81+
{
82+
break;
83+
}
84+
}
85+
}
86+
}
87+
Ok(())
88+
})();
89+
90+
crossterm::terminal::disable_raw_mode()?;
91+
result
92+
}

0 commit comments

Comments
 (0)