aboutsummaryrefslogtreecommitdiffstats
path: root/src/tmux.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2023-05-06 17:56:06 -0500
committerToby Vincent <tobyv13@gmail.com>2023-05-06 17:56:57 -0500
commitde5b70c5426311ce887e757c7397bed9107c83c0 (patch)
tree8da07e48b7e729122584a3681104396f51c5f54f /src/tmux.rs
parentbcdcdb0ada8d13950e22909250b6b6783866535e (diff)
feat: impl tmux session source and parser
Diffstat (limited to 'src/tmux.rs')
-rw-r--r--src/tmux.rs82
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)
+ }
+}