use crate::core::tmux::TmuxTarget;
use crate::daemon::tmux::TmuxDriver;
use super::manager::{ManagedError, ManagedTmuxDriver};
pub struct RealTmuxDriver {
driver: TmuxDriver,
}
impl RealTmuxDriver {
pub fn discover() -> Result<Self, ManagedError> {
let driver =
TmuxDriver::discover().map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))?;
Ok(Self { driver })
}
}
impl ManagedTmuxDriver for RealTmuxDriver {
fn create_session(&self, name: &str, workdir: &str) -> Result<(), ManagedError> {
self.driver
.create_session(name, Some(workdir))
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn kill_session(&self, name: &str) -> Result<(), ManagedError> {
self.driver
.kill_session(name)
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn send_line(&self, name: &str, text: &str) -> Result<(), ManagedError> {
self.driver
.send_line(&TmuxTarget::session(name), text)
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn send_keys_literal(&self, name: &str, text: &str) -> Result<(), ManagedError> {
self.driver
.send_keys_literal(&TmuxTarget::session(name), text)
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn send_interrupt(&self, name: &str) -> Result<(), ManagedError> {
self.driver
.send_interrupt(&TmuxTarget::session(name))
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn capture(&self, name: &str, lines: usize) -> Result<String, ManagedError> {
let lines = u32::try_from(lines).unwrap_or(u32::MAX);
self.driver
.capture(&TmuxTarget::session(name), Some(lines))
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn list_sessions(&self) -> Result<Vec<String>, ManagedError> {
self.driver
.list_sessions()
.map(|sessions| sessions.into_iter().map(|s| s.name).collect())
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
fn get_pane_cwd(&self, name: &str) -> Option<std::path::PathBuf> {
self.driver.pane_current_path(name)
}
fn set_environment(&self, name: &str, key: &str, value: &str) -> Result<(), ManagedError> {
self.driver
.set_environment(name, key, value)
.map_err(|e| ManagedError::TmuxUnavailable(e.to_string()))
}
}
pub struct NoopTmuxDriver;
impl ManagedTmuxDriver for NoopTmuxDriver {
fn create_session(&self, _name: &str, _workdir: &str) -> Result<(), ManagedError> {
Err(ManagedError::TmuxUnavailable("tmux not installed".into()))
}
fn kill_session(&self, _name: &str) -> Result<(), ManagedError> {
Ok(())
}
fn send_line(&self, _name: &str, _text: &str) -> Result<(), ManagedError> {
Err(ManagedError::TmuxUnavailable("tmux not installed".into()))
}
fn capture(&self, _name: &str, _lines: usize) -> Result<String, ManagedError> {
Ok(String::new())
}
fn list_sessions(&self) -> Result<Vec<String>, ManagedError> {
Ok(Vec::new())
}
fn set_environment(&self, _name: &str, _key: &str, _value: &str) -> Result<(), ManagedError> {
Err(ManagedError::TmuxUnavailable("tmux not installed".into()))
}
}
#[doc(hidden)]
pub struct FakeNoopTmuxDriver;
impl ManagedTmuxDriver for FakeNoopTmuxDriver {
fn create_session(&self, _name: &str, _workdir: &str) -> Result<(), ManagedError> {
Ok(())
}
fn kill_session(&self, _name: &str) -> Result<(), ManagedError> {
Ok(())
}
fn send_line(&self, _name: &str, _text: &str) -> Result<(), ManagedError> {
Ok(())
}
fn send_keys_literal(&self, _name: &str, _text: &str) -> Result<(), ManagedError> {
Ok(())
}
fn send_interrupt(&self, _name: &str) -> Result<(), ManagedError> {
Ok(())
}
fn capture(&self, _name: &str, _lines: usize) -> Result<String, ManagedError> {
Ok(String::new())
}
fn list_sessions(&self) -> Result<Vec<String>, ManagedError> {
Ok(Vec::new())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn real_tmux_constructs() {
let _ = RealTmuxDriver::discover();
}
#[test]
fn fake_noop_driver_accepts_create_session() {
let driver = FakeNoopTmuxDriver;
assert!(
driver.create_session("tmpm-test-abc123", "/tmp").is_ok(),
"FakeNoopTmuxDriver::create_session must succeed"
);
}
#[test]
fn noop_driver_set_environment_fails_loudly() {
let driver = NoopTmuxDriver;
assert!(driver.set_environment("s", "K", "v").is_err());
}
#[test]
fn fake_noop_driver_list_sessions_is_empty() {
let driver = FakeNoopTmuxDriver;
let sessions = driver.list_sessions().expect("list_sessions ok");
assert!(
sessions.is_empty(),
"FakeNoopTmuxDriver must see no live sessions"
);
}
}