1pub mod commands;
7pub mod config;
8pub mod output;
9
10use clap::{Parser, Subcommand};
11use std::error::Error;
12use crate::cli::commands::CliCommand;
13
14#[derive(Parser, Debug)]
16#[command(name = "nerve-cli")]
17#[command(about = "Nerve Framework System Debugging CLI")]
18#[command(version = "0.1.0")]
19#[command(propagate_version = true)]
20pub struct Cli {
21 #[command(flatten)]
23 pub config: CliConfig,
24
25 #[command(subcommand)]
27 pub command: Commands,
28}
29
30#[derive(Parser, Debug)]
32pub struct CliConfig {
33 #[arg(short, long, global = true)]
35 pub verbose: bool,
36
37 #[arg(short, long, global = true, default_value = "text")]
39 pub format: String,
40
41 #[arg(short, long, global = true)]
43 pub config_file: Option<String>,
44}
45
46#[derive(Subcommand, Debug)]
48pub enum Commands {
49 Status(commands::status::StatusCommand),
51
52 Memory(commands::memory::MemoryCommand),
54
55 Threads(commands::threads::ThreadsCommand),
57
58 Nodes(commands::nodes::NodesCommand),
60
61 Comms(commands::comms::CommsCommand),
63
64 Perf(commands::perf::PerfCommand),
66
67 Config(commands::config::ConfigCommand),
69
70 Debug(commands::debug::DebugCommand),
72}
73
74pub struct CliApp {
76 pub cli: Cli,
77}
78
79impl CliApp {
80 pub fn new() -> Self {
82 Self {
83 cli: Cli::parse(),
84 }
85 }
86
87 pub fn run(&self) -> Result<(), Box<dyn Error>> {
89 if self.cli.config.verbose {
90 println!("🔧 Nerve Framework CLI v0.1.0");
91 println!("📊 Running command: {:?}", self.cli.command);
92 }
93
94 match &self.cli.command {
95 Commands::Status(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
96 Commands::Memory(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
97 Commands::Threads(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
98 Commands::Nodes(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
99 Commands::Comms(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
100 Commands::Perf(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
101 Commands::Config(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
102 Commands::Debug(cmd) => cmd.execute(&self.cli.config).map_err(|e| e.into()),
103 }
104 }
105}
106
107#[derive(Debug, thiserror::Error)]
109pub enum CliError {
110 #[error("System error: {0}")]
111 SystemError(String),
112
113 #[error("Configuration error: {0}")]
114 ConfigError(String),
115
116 #[error("Command execution error: {0}")]
117 ExecutionError(String),
118
119 #[error("Output format error: {0}")]
120 OutputError(String),
121}
122
123impl From<Box<dyn Error>> for CliError {
124 fn from(error: Box<dyn Error>) -> Self {
125 CliError::SystemError(error.to_string())
126 }
127}