diff options
author | Toby Vincent <tobyv13@gmail.com> | 2023-05-06 17:56:06 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2023-05-06 17:56:57 -0500 |
commit | de5b70c5426311ce887e757c7397bed9107c83c0 (patch) | |
tree | 8da07e48b7e729122584a3681104396f51c5f54f /src/tmux.rs | |
parent | bcdcdb0ada8d13950e22909250b6b6783866535e (diff) |
feat: impl tmux session source and parser
Diffstat (limited to 'src/tmux.rs')
-rw-r--r-- | src/tmux.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/tmux.rs b/src/tmux.rs new file mode 100644 index 0000000..559242b --- /dev/null +++ b/src/tmux.rs @@ -0,0 +1,82 @@ +use std::{ffi::OsString, path::PathBuf, process::Command, time::Duration}; + +use crate::{parser::Parser, project::Project}; + +use self::error::Error; + +pub mod error; + +#[derive(Debug)] +pub struct Tmux; + +impl Tmux { + pub fn sessions() -> Result<Vec<PathBuf>, Error> { + let stdout = Command::new("tmux") + .arg("list-sessions") + .arg("-F") + .arg("#{session_path}") + .output()? + .stdout; + + Ok(std::str::from_utf8(&stdout)? + .lines() + .map(Into::into) + .collect()) + } + + pub fn get_session(&self, path_buf: PathBuf) -> Result<Project, Error> { + let mut filter = OsString::from("#{==:#{session_path},"); + filter.push(path_buf.as_os_str()); + filter.push("}"); + + // tmux list-sessions -f '#{==:#{session_path},/home/tobyv/src/projectr}' + let stdout = Command::new("tmux") + .arg("list-sessions") + .arg("-F") + .arg("#{session_path},#{session_last_attached},#{session_created}") + .arg("-f") + .arg(filter) + .output()? + .stdout; + + std::str::from_utf8(&stdout)? + .lines() + .map(Self::parse_project) + .inspect(|res| { + if let Err(err) = res { + tracing::warn!(%err, "Skipping invalid format") + } + }) + .flatten() + .max() + .ok_or(Error::NotFound) + } + + fn parse_project<T: AsRef<str>>(fmt_str: T) -> Result<Project, Error> { + let mut split = fmt_str.as_ref().split(','); + + let path_buf = split + .next() + .ok_or(Error::PathFormat(fmt_str.as_ref().to_string()))? + .into(); + + let timestamp = split + .next() + .ok_or(Error::TimestampFormat(fmt_str.as_ref().to_string()))? + .parse() + .map(Duration::from_secs)?; + + Ok(Project { + timestamp, + path_buf, + }) + } +} + +impl Parser for Tmux { + type Error = Error; + + fn parse(&self, path_buf: PathBuf) -> Result<Project, Self::Error> { + self.get_session(path_buf) + } +} |