From f4676eb2c3897218e6a73778709d3d33fab946e2 Mon Sep 17 00:00:00 2001 From: quak Date: Mon, 27 Jan 2025 23:57:48 +0100 Subject: [PATCH] implemented `push` to stack entry by number --- src/arguments.rs | 2 +- src/main.rs | 34 ++++++++++++++++++++++++---------- src/stack.rs | 15 +++++++-------- todo.md | 2 +- 4 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/arguments.rs b/src/arguments.rs index bda53e6..57de548 100644 --- a/src/arguments.rs +++ b/src/arguments.rs @@ -39,7 +39,7 @@ pub struct PushArgs { pub show_stack: Option, /// change to - pub path: Option, + pub path: Option, } #[derive(Debug, Clone, Args)] diff --git a/src/main.rs b/src/main.rs index 430632c..cf3be23 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,10 +11,12 @@ use clap::Parser; use config::*; use bookmarks::*; use config_parser::*; +use dirs::home_dir; use output::Output; use stack::Stack; use util::to_rooted; -use std::env::{current_dir, var}; +use std::char; +use std::env::current_dir; use std::io::{Error, Result}; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -72,17 +74,29 @@ fn main() -> Result<()> { } fn handle_push(args: &PushArgs, config: &Config, stack: &mut Stack, output: &mut Output) -> Result<()> { - let path = match args.path.clone() { + const PREFIX: char = '='; + let mut path_string = match args.path.clone() { Some(value) => value, None => { - let home_dir = match var("HOME") { - Ok(value) => value, - Err(error) => return Err(Error::other(error.to_string())), - }; - match PathBuf::from_str(&home_dir) { - Ok(value) => value, - Err(error) => return Err(Error::other(error.to_string())), - } + String::new() + } + }; + let path: PathBuf = if path_string.is_empty() { + match home_dir() { + Some(value) => value, + None => return Err(Error::other("-- failed to determine home directory")), + } + } else if path_string.starts_with(PREFIX) { + path_string = path_string.trim_start_matches(PREFIX).to_string(); + let number: usize = match path_string.parse() { + Ok(value) => value, + Err(_) => return Err(Error::other("-- push : failed to convert path argument to number")), + }; + stack.get_entry_by_number(number)?.to_path_buf() + } else { + match PathBuf::from_str(&path_string) { + Ok(value) => value, + Err(_) => return Err(Error::other("-- failed to create PathBuf from argument")), } }; push_path(&path, stack, config, output)?; diff --git a/src/stack.rs b/src/stack.rs index ac1b8d1..4fff69a 100644 --- a/src/stack.rs +++ b/src/stack.rs @@ -1,6 +1,6 @@ #![allow(dead_code)] -use std::fs; +use std::{fs, usize}; use std::fs::File; use std::io::{Error, Result}; use std::path::{Path, PathBuf}; @@ -112,13 +112,12 @@ impl Stack { /// return nth last entry pub fn get_entry_by_number(&mut self, entry_number: usize) -> Result<&PathBuf> { // index from the end of the vector as new entries are appended at the end of the list - let index = match self.stack.len().checked_sub(entry_number) { - Some(value) => value, - None => return Err(Error::other("-- no entry found at request index")), - }; - match self.stack.get(index) { - Some(item) => Ok(item), - None => Err(Error::other("-- failed to retrieve stack entry by number")), + if entry_number >= self.stack.len() { + return Err(Error::other(format!("-- requested item ({entry_number}) out of bounds (stack.len() = {})", self.stack.len()))); + } + match self.stack.iter().rev().nth(entry_number) { + Some(value) => Ok(value), + None => return Err(Error::other("-- failed to retrieve stack element #{entry_number}")), } } diff --git a/todo.md b/todo.md index db1c0fd..13e64f9 100644 --- a/todo.md +++ b/todo.md @@ -15,7 +15,7 @@ - [x] color option for punctuation (mostly '/') - [x] bookmarks - [x] do not resolve links in bookmarks -- [ ] push to push path in stack +- [x] push to push path in stack - [x] write documentation - [x] change config file extension to `.toml` - [x] add bash completions