diff --git a/Cargo.lock b/Cargo.lock index 73f7a2a..1b7f142 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -264,6 +264,7 @@ version = "0.1.0" dependencies = [ "clap", "dir_rpc", + "shlex", "vfs_rpc", ] @@ -326,6 +327,12 @@ dependencies = [ "syn", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "smallvec" version = "1.13.2" diff --git a/Cargo.toml b/Cargo.toml index 3e0e9fc..1cb9ff5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,5 @@ edition = "2021" [dependencies] clap = { version = "4.5.18", features = ["derive"] } dir_rpc = { version = "0.1.0", path = "../dir_rpc" } +shlex = "1.3.0" vfs_rpc = { version = "0.1.0", path = "../vfs/vfs_rpc" } diff --git a/src/main.rs b/src/main.rs index ae9e1d8..ef44c22 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,30 +1,19 @@ use std::{ io::{self, Write}, os::mikros::syscalls, - path::Path, + path::{Path, PathBuf}, }; -use clap::{Parser, Subcommand}; +use clap::Parser; #[derive(Parser, Debug)] -struct Cli { - #[command(subcommand)] - command: Commands +struct Ls { + path: Option, } -#[derive(Subcommand, Debug)] -enum Commands { - Pwd, - Ls { - path: Option - }, - Cat { - path: String, - }, - Exit { - path: String, - }, - Help, +#[derive(Parser, Debug)] +struct Cat { + path: PathBuf, } fn main() { @@ -56,23 +45,30 @@ fn main() { if line.is_empty() { continue; } - let cmd = line.split(' ').collect::>(); - dbg!(Cli::try_parse_from(&cmd)); - match cmd[0] { + let Some(cmd) = shlex::split(line) else { + println!("Syntax error"); + continue; + }; + match cmd[0].as_str() { "pwd" => println!("{}", cwd.to_string_lossy()), "ls" => { - let mut path = if cmd.len() > 1 { - Path::new(cmd[1]).to_owned() - } else { - cwd.clone() + let cmd = match Ls::try_parse_from(&cmd) { + Ok(cmd) => cmd, + Err(err) => { + err.print().unwrap(); + continue; + } }; - if path.is_relative() { + let cmd_path = cmd.path.clone().unwrap_or(PathBuf::new()); + let abs_path = if cmd_path.is_relative() { let mut abs_path = cwd.clone(); - abs_path.push(path); - path = abs_path; - } - let Ok((fs_pid, dir_fd)) = vfs_client.open_dir(&path) else { - println!("psh: {}: failed to open", path.to_string_lossy()); + abs_path.push(cmd_path.clone()); + abs_path + } else { + cmd_path.clone() + }; + let Ok((fs_pid, dir_fd)) = vfs_client.open_dir(&abs_path) else { + println!("ls: {}: failed to open", cmd_path.display()); continue; }; let fs_client = dir_rpc::Client::new(fs_pid); @@ -81,18 +77,22 @@ fn main() { } } "cat" => { - if cmd.len() < 2 { - println!("Usage: cat "); - continue; - } - let mut path = Path::new(cmd[1]).to_owned(); - if path.is_relative() { + let cmd = match Cat::try_parse_from(&cmd) { + Ok(cmd) => cmd, + Err(err) => { + err.print().unwrap(); + continue; + } + }; + let abs_path = if cmd.path.is_relative() { let mut abs_path = cwd.clone(); - abs_path.push(path); - path = abs_path; - } - let Ok(contents) = std::fs::read(&path) else { - println!("psh: {}: failed to read", path.to_string_lossy()); + abs_path.push(cmd.path.clone()); + abs_path + } else { + cmd.path.clone() + }; + let Ok(contents) = std::fs::read(&abs_path) else { + println!("cat: {}: failed to read", cmd.path.display()); continue; }; io::stdout().lock().write_all(&contents).unwrap(); @@ -109,12 +109,11 @@ fn main() { println!("Commands:"); println!("pwd"); println!("ls"); - println!("cat"); println!("exit"); println!("help"); } - _ => println!("psh: command not found: {}", cmd[0]), + _ => println!("psh: {}: command not found", cmd[0]), } } }