summaryrefslogtreecommitdiffstats
path: root/src/history.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-04-03 19:12:14 -0500
committerToby Vincent <tobyv13@gmail.com>2023-04-03 19:12:14 -0500
commitc94960b49f463b3c4a7da9fb1b6b2c122f7dd125 (patch)
tree6be101dd21b61775313e04b6c695629b183f48b4 /src/history.rs
parent8a6631053a48a64f0c3b21ec0d92b6b687de9638 (diff)
refactor: clean up logic and impl trait for writing sessions
Diffstat (limited to 'src/history.rs')
-rw-r--r--src/history.rs69
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)),
+ }
}
}