1#![warn(missing_docs)]
2
3use std::error::Error;
8use tracing::info;
9
10pub trait Parse {
12 fn parse(args: &mut Vec<String>) -> Self;
14}
15
16impl Parse for String {
18 fn parse(args: &mut Vec<String>) -> Self {
19 if args.is_empty() {
20 panic!("Expected string argument");
21 }
22 args.remove(0)
23 }
24}
25
26impl Parse for i32 {
28 fn parse(args: &mut Vec<String>) -> Self {
29 if args.is_empty() {
30 panic!("Expected integer argument");
31 }
32 args.remove(0).parse().expect("Invalid integer")
33 }
34}
35
36impl Parse for u32 {
38 fn parse(args: &mut Vec<String>) -> Self {
39 if args.is_empty() {
40 panic!("Expected unsigned integer argument");
41 }
42 args.remove(0).parse().expect("Invalid unsigned integer")
43 }
44}
45
46impl Parse for bool {
48 fn parse(args: &mut Vec<String>) -> Self {
49 if args.is_empty() {
50 panic!("Expected boolean argument");
51 }
52 args.remove(0).parse().expect("Invalid boolean")
53 }
54}
55
56#[derive(Debug)]
58pub struct Cli {
59 pub command: Command,
61}
62
63#[derive(Debug)]
65pub enum Command {
66 Init {
68 name: String,
70 },
71 Build,
73 Dev,
75 Check,
77}
78
79impl Parse for Cli {
81 fn parse(args: &mut Vec<String>) -> Self {
82 Self { command: Command::parse(args) }
83 }
84}
85
86impl Parse for Command {
88 fn parse(args: &mut Vec<String>) -> Self {
89 if args.is_empty() {
90 panic!("Expected command");
91 }
92 let cmd = args.remove(0);
93 match cmd.as_str() {
94 "init" => Self::Init { name: String::parse(args) },
95 "build" => Self::Build,
96 "dev" => Self::Dev,
97 "check" => Self::Check,
98 _ => panic!("Unknown command: {}", cmd),
99 }
100 }
101}
102
103pub fn init_cli() {
105 tracing_subscriber::fmt().with_env_filter(tracing_subscriber::EnvFilter::from_default_env()).init();
107
108 info!("CLI initialized");
109}
110
111pub fn execute_command(cli: Cli) -> Result<(), Box<dyn Error>> {
113 match cli.command {
114 Command::Init { name } => {
115 info!("Initializing project: {}", name);
116 let mut pb = itools_tui::ProgressBar::new(100, 50);
118 for i in 0..=100 {
119 pb.update(i);
120 std::thread::sleep(std::time::Duration::from_millis(50));
121 }
122 pb.finish();
123 Ok(())
124 }
125 Command::Build => {
126 info!("Building project");
127 itools_tui::loading_animation(std::time::Duration::from_secs(3), "Building...");
129 Ok(())
130 }
131 Command::Dev => {
132 info!("Starting dev server");
133 let items = ["Option 1", "Option 2", "Option 3"];
135 if let Some(choice) = itools_tui::select(&items, "Please select an option:") {
136 info!("Selected: {}", items[choice]);
137 }
138 Ok(())
139 }
140 Command::Check => {
141 info!("Checking project");
142 let mut pb = itools_tui::ProgressBar::new(50, 30);
144 for i in 0..=50 {
145 pb.update(i);
146 std::thread::sleep(std::time::Duration::from_millis(100));
147 }
148 pb.finish();
149 Ok(())
150 }
151 }
152}