use crate::commands::constants::*;
use crate::{Error, TmuxCommand, TmuxCommands, TmuxOutput};
use std::borrow::Cow;
use std::process::{Child, Command, ExitStatus, Stdio};
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
pub enum StdIO {
#[default]
Inherit,
Null,
Piped,
}
impl From<StdIO> for Stdio {
fn from(item: StdIO) -> Self {
match item {
StdIO::Inherit => Stdio::inherit(),
StdIO::Piped => Stdio::piped(),
StdIO::Null => Stdio::null(),
}
}
}
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
pub struct Tmux<'a> {
#[cfg(feature = "tmux_0_8")]
pub colours256: bool,
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_9")))]
pub colours88: bool,
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_5")))]
pub default_colours: bool,
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_2_1")))]
pub prevent_msg: bool,
#[cfg(feature = "tmux_1_8")]
pub control_mode: bool,
#[cfg(feature = "tmux_1_8")]
pub disable_echo: bool,
#[cfg(feature = "tmux_3_2")]
pub no_daemon: bool,
#[cfg(feature = "tmux_3_6")]
pub help: bool,
#[cfg(feature = "tmux_1_5")]
pub login_shell: bool,
#[cfg(feature = "tmux_3_4")]
pub no_start: bool,
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_5")))]
pub unlock: bool,
#[cfg(feature = "tmux_0_8")]
pub force_utf8: bool,
#[cfg(feature = "tmux_0_8")]
pub verbose_logging: bool,
#[cfg(feature = "tmux_0_8")]
pub version: bool,
#[cfg(feature = "tmux_1_5")]
pub shell_command: Option<Cow<'a, str>>,
#[cfg(feature = "tmux_0_8")]
pub file: Option<Cow<'a, str>>,
#[cfg(feature = "tmux_0_8")]
pub socket_name: Option<Cow<'a, str>>,
#[cfg(feature = "tmux_0_8")]
pub socket_path: Option<Cow<'a, str>>,
#[cfg(feature = "tmux_3_2")]
pub features: Option<Cow<'a, str>>,
pub command: Option<TmuxCommands<'a>>,
pub stdin: Option<StdIO>,
pub stdout: Option<StdIO>,
pub stderr: Option<StdIO>,
}
impl<'a> Tmux<'a> {
pub fn new() -> Self {
Default::default()
}
#[cfg(feature = "tmux_0_8")]
pub fn colours256(mut self) -> Self {
self.colours256 = true;
self
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_9")))]
pub fn colours88(mut self) -> Self {
self.colours88 = true;
self
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_5")))]
pub fn default_colours(mut self) -> Self {
self.default_colours = true;
self
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_2_1")))]
pub fn prevent_msg(mut self) -> Self {
self.prevent_msg = true;
self
}
#[cfg(feature = "tmux_1_8")]
pub fn control_mode(mut self) -> Self {
self.control_mode = true;
self
}
#[cfg(feature = "tmux_1_8")]
pub fn disable_echo(mut self) -> Self {
self.disable_echo = true;
self
}
#[cfg(feature = "tmux_3_2")]
pub fn no_daemon(mut self) -> Self {
self.no_daemon = true;
self
}
#[cfg(feature = "tmux_3_6")]
pub fn help(mut self) -> Self {
self.help = true;
self
}
#[cfg(feature = "tmux_1_5")]
pub fn login_shell(mut self) -> Self {
self.login_shell = true;
self
}
#[cfg(feature = "tmux_3_4")]
pub fn no_start(mut self) -> Self {
self.no_start = true;
self
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_5")))]
pub fn unlock(mut self) -> Self {
self.unlock = true;
self
}
#[cfg(feature = "tmux_0_8")]
pub fn force_utf8(mut self) -> Self {
self.force_utf8 = true;
self
}
#[cfg(feature = "tmux_0_8")]
pub fn verbose_logging(mut self) -> Self {
self.verbose_logging = true;
self
}
#[cfg(feature = "tmux_0_8")]
pub fn version(mut self) -> Self {
self.version = true;
self
}
#[cfg(feature = "tmux_1_5")]
pub fn shell_command<S: Into<Cow<'a, str>>>(mut self, shell_command: S) -> Self {
self.shell_command = Some(shell_command.into());
self
}
#[cfg(feature = "tmux_0_8")]
pub fn file<S: Into<Cow<'a, str>>>(mut self, file: S) -> Self {
self.file = Some(file.into());
self
}
#[cfg(feature = "tmux_0_8")]
pub fn socket_name<S: Into<Cow<'a, str>>>(mut self, socket_name: S) -> Self {
self.socket_name = Some(socket_name.into());
self
}
#[cfg(feature = "tmux_0_8")]
pub fn socket_path<S: Into<Cow<'a, str>>>(mut self, socket_path: S) -> Self {
self.socket_path = Some(socket_path.into());
self
}
#[cfg(feature = "tmux_3_2")]
pub fn features<S: Into<Cow<'a, str>>>(mut self, features: S) -> Self {
self.features = Some(features.into());
self
}
#[cfg(feature = "tmux_0_8")]
pub fn command<T: Into<TmuxCommand<'a>>>(mut self, command: T) -> Self {
self.command
.get_or_insert(TmuxCommands::new())
.push(command.into());
self
}
pub fn build(self) -> TmuxCommand<'a> {
let mut cmd = TmuxCommand::new();
cmd.name(TMUX);
#[cfg(feature = "tmux_0_8")]
if self.colours256 {
cmd.push_flag(_2_KEY);
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_9")))]
if self.colours88 {
cmd.push_flag(_8_KEY);
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_5")))]
if self.default_colours {
cmd.push_flag(D_LOWERCASE_KEY);
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_2_1")))]
if self.prevent_msg {
cmd.push_flag(Q_LOWERCASE_KEY);
}
#[cfg(feature = "tmux_1_8")]
if self.control_mode {
cmd.push_flag(C_UPPERCASE_KEY);
}
#[cfg(feature = "tmux_1_8")]
if self.disable_echo {
cmd.push_flag(CC_UPPERCASE_KEY);
}
#[cfg(feature = "tmux_3_2")]
if self.no_daemon {
cmd.push_flag(D_UPPERCASE_KEY);
}
#[cfg(feature = "tmux_3_6")]
if self.help {
cmd.push_flag(H_LOWERCASE_KEY);
}
#[cfg(feature = "tmux_1_5")]
if self.login_shell {
cmd.push_flag(L_LOWERCASE_KEY);
}
#[cfg(feature = "tmux_3_4")]
if self.no_start {
cmd.push_flag(N_UPPERCASE_KEY);
}
#[cfg(all(feature = "tmux_0_8", not(feature = "tmux_1_5")))]
if self.unlock {
cmd.push_flag(U_UPPERCASE_KEY);
}
#[cfg(feature = "tmux_0_8")]
if self.force_utf8 {
cmd.push_flag(U_LOWERCASE_KEY);
}
#[cfg(feature = "tmux_0_8")]
if self.verbose_logging {
cmd.push_flag(V_LOWERCASE_KEY);
}
#[cfg(feature = "tmux_0_8")]
if self.version {
cmd.push_flag(V_UPPERCASE_KEY);
}
#[cfg(feature = "tmux_1_5")]
if let Some(shell_command) = self.shell_command {
cmd.push_option(C_LOWERCASE_KEY, shell_command);
}
#[cfg(feature = "tmux_0_8")]
if let Some(file) = self.file {
cmd.push_option(F_LOWERCASE_KEY, file);
}
#[cfg(feature = "tmux_0_8")]
if let Some(socket_name) = self.socket_name {
cmd.push_option(L_UPPERCASE_KEY, socket_name);
}
#[cfg(feature = "tmux_0_8")]
if let Some(socket_path) = self.socket_path {
cmd.push_option(S_UPPERCASE_KEY, socket_path);
}
#[cfg(feature = "tmux_3_2")]
if let Some(features) = self.features {
cmd.push_option(T_UPPERCASE_KEY, features);
}
#[cfg(feature = "tmux_0_8")]
if let Some(command) = self.command {
cmd.push_cmds(command);
}
cmd
}
pub fn into_command(self) -> Command {
Command::from(self)
}
pub fn with_command<T: Into<TmuxCommand<'a>>>(command: T) -> Self {
Tmux::new().command(command.into())
}
pub fn with_commands(commands: TmuxCommands<'a>) -> Self {
Tmux::new().commands(commands)
}
pub fn add_command<T: Into<TmuxCommand<'a>>>(mut self, command: T) -> Self {
self.command
.get_or_insert(TmuxCommands::new())
.push(command.into());
self
}
pub fn commands(mut self, commands: TmuxCommands<'a>) -> Self {
self.command = Some(commands);
self
}
}
impl<'a> Tmux<'a> {
pub fn output(self) -> Result<TmuxOutput, Error> {
let mut command = Command::from(self);
let output = command.output()?;
Ok(TmuxOutput(output))
}
pub fn spawn(self) -> Result<Child, Error> {
let mut command = Command::from(self);
let child = command.spawn()?;
Ok(child)
}
pub fn status(self) -> Result<ExitStatus, Error> {
let mut command = Command::from(self);
let status = command.status()?;
Ok(status)
}
pub fn stdin(mut self, stdin: Option<StdIO>) -> Self {
self.stdin = stdin;
self
}
pub fn stdout(mut self, stdout: Option<StdIO>) -> Self {
self.stdout = stdout;
self
}
pub fn stderr(mut self, stderr: Option<StdIO>) -> Self {
self.stderr = stderr;
self
}
}
impl<'a> From<Tmux<'a>> for Command {
fn from(item: Tmux<'a>) -> Self {
let mut command: Command = item.clone().build().into();
if let Some(stdio) = item.stdin {
command.stdin::<Stdio>(stdio.into());
} else {
command.stdin(Stdio::inherit());
}
if let Some(stdio) = item.stdout {
command.stdout::<Stdio>(stdio.into());
}
if let Some(stdio) = item.stderr {
command.stderr::<Stdio>(stdio.into());
}
command
}
}