From ce096d2430647d946ff3a18f6a2ca77a7a36a33c Mon Sep 17 00:00:00 2001 From: quak Date: Wed, 27 Nov 2024 23:44:47 +0100 Subject: [PATCH] implemented push and pop commands, push command saves the wrong path though --- bash_setup.sh | 11 +++----- src/arguments.rs | 29 ++++++++++++--------- src/main.rs | 43 ++++++++++++++++++++++++++---- src/stack.rs | 68 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 113 insertions(+), 38 deletions(-) diff --git a/bash_setup.sh b/bash_setup.sh index f84fe02..90e0a60 100644 --- a/bash_setup.sh +++ b/bash_setup.sh @@ -4,18 +4,15 @@ export PATH="$PATH:$PWD/target/debug/" pid=( $(ps -o ppid) ) arg_pid=" --pid ${pid[-2]} " -nav() { - cd "$(navigate ${arg_pid} $*)" -} push() { - cd "$(navigate push ${arg_pid} $*)" + \builtin cd -- "$(navigate ${arg_pid} push $@)" } pop() { - cd "$(navigate pop ${arg_pid} $*)" + \builtin cd -- "$(navigate ${arg_pid} pop $@)" } stack() { - "navigate stack ${arg_pid}" -} \ No newline at end of file + echo "$(navigate ${arg_pid} show $*)" +} diff --git a/src/arguments.rs b/src/arguments.rs index 58587fe..a4287f8 100644 --- a/src/arguments.rs +++ b/src/arguments.rs @@ -1,17 +1,18 @@ use clap::{Parser, Args, Subcommand}; +use std::path::PathBuf; /// implements stack for cd wrapper script #[derive(Parser, Debug)] #[clap(author, version, about, long_about=None)] pub struct Arguments { - /// subcommand - #[command(subcommand)] - pub action: Action, - /// process id of parent shell #[arg(short, long)] pub pid: u32, + + /// subcommand + #[command(subcommand)] + pub action: Action, } #[derive(Debug, Clone, Subcommand)] @@ -22,8 +23,8 @@ pub enum Action { /// navigate to last entry in stack and remove it pop(PopArgs), - /// display stack - stack(StackArgs), + /// show stack + show(ShowArgs), /// navigate to bookmark and add current path to the stack bookmark(BookmarkArgs), @@ -33,33 +34,35 @@ pub enum Action { pub struct PushArgs { /// show stack #[arg(short, long)] - show_stack: Option, + pub show_stack: Option, /// change to - path: String, + pub path: PathBuf, } #[derive(Debug, Clone, Args)] pub struct PopArgs { /// show stack #[arg(short, long)] - show_stack: Option, + pub show_stack: Option, } #[derive(Debug, Clone, Args)] -pub struct StackArgs { +pub struct ShowArgs { /// hide entry numbers #[arg(short='n', long)] - hide_numbers: Option, + pub hide_numbers: Option, /// show n entries #[arg(short, long="lines")] - lines: Option, + pub lines: Option, } #[derive(Debug, Clone, Args)] pub struct BookmarkArgs { /// show stack #[arg(short, long)] - show_stack: Option, + pub show_stack: Option, + + pub mark: String, } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 9505c8e..d5554ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,46 @@ mod arguments; mod stack; -use clap::Parser; -use arguments::Arguments; +use std::io::{Result, Error, ErrorKind}; +use std::path::PathBuf; +use clap::{FromArgMatches, Parser}; +use arguments::*; use stack::Stack; -fn main() { +fn main() -> Result<()> { let args = Arguments::parse(); + let mut stack = Stack::new(args.pid).expect("failed to build stack"); - let stack = Stack::new(args.pid); -} \ No newline at end of file + return match args.action { + Action::push(push_args) => handle_push(&push_args, &mut stack), + Action::pop(pop_args) => handle_pop(&pop_args, &mut stack), + Action::show(show_args) => handle_show(&show_args, &mut stack), + Action::bookmark(bookmark_args) => handle_bookmark(&bookmark_args, &mut stack), + _ => Err(Error::new(ErrorKind::Other, "unknown subcommand")), + }; +} + +pub fn handle_push (args: &PushArgs, stack: &mut Stack) -> Result<()> { // TODO: handle arguments + stack.push_entry(&args.path)?; + println!("{}", args.path.to_str().unwrap()); + return Ok(()); +} + +pub fn handle_pop (args: &PopArgs, stack: &mut Stack) -> Result<()> { // TODO: handle arguments + let path = stack.pop_entry()?; + println!("{}", path.to_str().unwrap()); + return Ok(()); +} + +pub fn handle_show (args: &ShowArgs, stack: &mut Stack) -> Result<()> { // TODO: handle arguments + let output = stack.get_stack()?; + for item in output { + println!("{}", item.to_str().unwrap()); + } + return Ok(()); +} + +pub fn handle_bookmark (args: &BookmarkArgs, stack: &mut Stack) -> Result<()> { // TODO: handle arguments + return Ok(()); +} diff --git a/src/stack.rs b/src/stack.rs index 13c4f98..a380b27 100644 --- a/src/stack.rs +++ b/src/stack.rs @@ -1,9 +1,9 @@ -use std::io::{Result}; use std::fs; use std::fs::File; use std::path::{PathBuf}; use std::str::FromStr; +use std::io::{Result, Error, ErrorKind}; use sysinfo::{System, Pid}; @@ -11,6 +11,7 @@ use sysinfo::{System, Pid}; pub struct Stack { pid: u32, + path: PathBuf, stack: Vec, } @@ -20,29 +21,57 @@ impl Stack pub fn new(process_id: u32) -> Result { let mut stack: Stack = Stack{ pid : process_id, + path : PathBuf::new(), stack : Vec::::new(), }; - stack.stack = stack.build_stack()?; + _ = stack.build_stack()?; return Ok(stack); } + /** + * return stack + */ + pub fn get_stack(&mut self) -> Result<&Vec> { + return Ok(&self.stack); + } + /** * push entry to stack * returns updated stack */ - pub fn push_entry(&mut self, path: PathBuf) -> Vec { - self.stack.push(path); - return self.stack.clone(); + pub fn push_entry(&mut self, path: &PathBuf) -> Result<&Vec> { + let abs_path = path.canonicalize()?; + self.stack.push(abs_path); + self.write_stack_file()?; + return Ok(&self.stack); } /** * pop entry from stack * return poppe entry */ - pub fn pop_entry(&mut self) -> PathBuf { - return self.stack.pop().unwrap(); + pub fn pop_entry(&mut self) -> Result { + let entry = self.stack.pop(); + self.write_stack_file()?; + + return match entry { + Some(entry) => Ok(entry), + None => Err(Error::new(ErrorKind::Other, "pop failed to retrieve item from stack")), + } + } + + /** + * get entry by number + * return nth last entry + */ + pub fn get_entry_by_number(&mut self, entry_number: u32) -> Result<&PathBuf> { + if entry_number > (self.stack.len() as u32 - 1) { + return Err(Error::new(ErrorKind::Other, "requested entry number is out of bounds")); + } + // index from the end of the vector as new entries are appended at the end of the list + return Ok(&self.stack[self.stack.len() - (entry_number as usize)]); } /** @@ -69,14 +98,14 @@ impl Stack let _ = fs::create_dir(stack_dir.clone())?; } - let mut stack_file_path = stack_dir.clone(); - stack_file_path.push(PathBuf::from(&self.pid.to_string())); - if stack_file_path.is_file() { + self.path = stack_dir.clone(); + self.path.push(PathBuf::from(&self.pid.to_string())); + if self.path.is_file() { // read and parse stack file - let _ = self.parse_stack_file(stack_file_path); + _ = self.read_stack_file(&self.path.clone())?; } else { // create stack file and store current path - let _ = File::create(stack_file_path.clone())?; + _ = File::create(self.path.clone())?; } return Ok(vec![stack_dir]); @@ -85,7 +114,7 @@ impl Stack /** * parse stack file */ - fn parse_stack_file(&mut self, stack_file_path: PathBuf) -> Result<()> { + fn read_stack_file(&mut self, stack_file_path: &PathBuf) -> Result<()> { let stack = fs::read_to_string(stack_file_path)?; let stack = stack.split("\n"); for entry in stack { @@ -95,5 +124,18 @@ impl Stack return Ok(()); } + /** + * write stack current stack to file to save it for next execution + */ + fn write_stack_file(&mut self) -> Result<()> { + let mut output = Vec::<&str>::new(); + for entry in &self.stack { + output.push(entry.to_str().expect("failed to convert stack entry to string")); + } + fs::write(self.path.clone(), output.join("\n"))?; + + return Ok(()) + } + } // end `impl database`