use std::{
path::{Path, PathBuf},
process::Child,
};
use log::debug;
use crate::{Error, Result, Terminal};
#[derive(Debug)]
pub struct Application {
pub command: String,
pub args: Vec<String>,
pub title: Option<String>,
pub class: Option<String>,
pub working_dir: Option<PathBuf>,
pub hold: bool,
}
impl Application {
#[must_use]
pub fn new(cmd: &str) -> Self {
Self {
command: cmd.to_string(),
args: Vec::new(),
title: None,
class: None,
working_dir: None,
hold: false,
}
}
#[must_use]
pub fn with_arg(mut self, arg: &str) -> Self {
self.args.push(arg.to_string());
self
}
#[must_use]
pub fn with_args(mut self, args: &Vec<&str>) -> Self {
self.args.extend(args.iter().map(ToString::to_string));
self
}
#[must_use]
pub fn with_title(mut self, title: &str) -> Self {
self.title = Some(title.to_string());
self
}
#[must_use]
pub fn with_class(mut self, class: &str) -> Self {
self.class = Some(class.to_string());
self
}
#[must_use]
pub fn with_working_dir(mut self, path: &Path) -> Self {
self.working_dir = Some(path.into());
self
}
#[must_use]
pub fn with_hold(mut self, keep_open: bool) -> Self {
self.hold = keep_open;
self
}
pub fn launch(&self) -> Result<Child> {
if let Some(term) = Terminal::find_available() {
return self.launch_with(&term);
}
Err(Error::NoSupportedTerminalAvailable)
}
pub fn launch_with(&self, terminal: &Terminal) -> Result<Child> {
let mut cmd = terminal.build_command(self)?;
debug!("Launching: {cmd:?}");
Ok(cmd.spawn()?)
}
}