diff options
author | Toby Vincent <tobyv13@gmail.com> | 2023-04-03 19:12:14 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2023-04-03 19:12:14 -0500 |
commit | c94960b49f463b3c4a7da9fb1b6b2c122f7dd125 (patch) | |
tree | 6be101dd21b61775313e04b6c695629b183f48b4 /src/history.rs | |
parent | 8a6631053a48a64f0c3b21ec0d92b6b687de9638 (diff) |
refactor: clean up logic and impl trait for writing sessions
Diffstat (limited to 'src/history.rs')
-rw-r--r-- | src/history.rs | 69 |
1 files changed, 43 insertions, 26 deletions
diff --git a/src/history.rs b/src/history.rs index 863be8e..0394e3d 100644 --- a/src/history.rs +++ b/src/history.rs @@ -1,60 +1,77 @@ use std::{ fs::File, - io::{BufRead, BufReader, Write}, + io::{BufRead, BufReader, ErrorKind}, path::PathBuf, }; +use clap::Args; use directories::ProjectDirs; -use crate::Session; +use crate::{session::SessionWriter, Session}; -pub use error::Error; - -mod error; - -#[derive(Debug)] +#[derive(Debug, Clone, Args)] +#[group(skip)] pub struct History { - pub file: File, - pub entries: Vec<Session>, + /// Update the history file from the current sessions + #[arg(short, long)] + pub update: bool, + + /// path to history file [default: $XDG_DATA_HOME/sshr/history] + #[arg(short = 'f', long = "history_file")] + path: Option<PathBuf>, } impl History { - pub fn open(history_file: PathBuf) -> Result<Self, std::io::Error> { - let file = File::options().write(true).open(&history_file)?; + pub fn new(History { update, path }: History) -> Self { + Self { + path: path.or_else(History::default_path), + update, + } + } + + pub fn read(&self) -> Result<Vec<Session>, std::io::Error> { + let Some(path) = &self.path() else { + tracing::warn!(?self.path, "History file does not exist"); + return Ok(Vec::new()); + }; - let entries = BufReader::new(File::open(history_file)?) + let sessions = BufReader::new(File::open(path)?) .lines() .flatten() .flat_map(|item| ron::from_str(&item)) .collect(); - Ok(Self { file, entries }) + Ok(sessions) } - pub fn default_path() -> Option<PathBuf> { + fn default_path() -> Option<PathBuf> { ProjectDirs::from("", "", env!("CARGO_CRATE_NAME"))? .state_dir()? .join("history") .into() } -} -impl IntoIterator for History { - type Item = Session; + pub fn path(&self) -> Option<PathBuf> { + self.path.clone().or_else(History::default_path) + } +} - type IntoIter = std::vec::IntoIter<Self::Item>; +impl SessionWriter for History { + type Writer = File; + type Error = ron::Error; - fn into_iter(self) -> Self::IntoIter { - self.entries.into_iter() + fn format(&self, session: &Session) -> Result<String, Self::Error> { + ron::to_string(session) } -} -impl Write for History { - fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { - self.file.write(buf) + fn filter(&self, session: &Session) -> bool { + self.update && !matches!(session.state, crate::State::Discovered) } - fn flush(&mut self) -> std::io::Result<()> { - self.file.flush() + fn writer(&self) -> Result<Self::Writer, std::io::Error> { + match &self.path { + Some(path) => File::create(path), + None => Err(std::io::Error::from(ErrorKind::NotFound)), + } } } |