tas/src/cli/show.rs

118 lines
3.5 KiB
Rust

//! Copyright (C) 2022, Dmitriy Pleshevskiy <dmitriy@ideascup.me>
//!
//! tas is free software: you can redistribute it and/or modify
//! it under the terms of the GNU General Public License as published by
//! the Free Software Foundation, either version 3 of the License, or
//! (at your option) any later version.
//!
//! tas is distributed in the hope that it will be useful,
//! but WITHOUT ANY WARRANTY; without even the implied warranty of
//! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//! GNU General Public License for more details.
//!
//! You should have received a copy of the GNU General Public License
//! along with tas. If not, see <https://www.gnu.org/licenses/>.
//!
use std::io::Write;
use std::process::{Command, Stdio};
use crate::cli::print_task_detail;
use crate::domain::CurrentTaskInfo;
use crate::repo::Repository;
#[derive(clap::Args)]
pub struct Args {
#[clap(short, long)]
clip: bool,
part: Option<PrintPart>,
}
#[derive(clap::ValueEnum, Clone)]
enum PrintPart {
Project,
DirPath,
Link,
}
impl std::str::FromStr for PrintPart {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"project" => Ok(PrintPart::Project),
"dir" => Ok(PrintPart::DirPath),
"link" => Ok(PrintPart::Link),
_ => Err("Available parts: dir, link, project"),
}
}
}
pub fn execute(repo: impl Repository, args: Args) {
let task = match repo.get_current_task_opt() {
Ok(None) => {
return eprintln!("You don't have an active task.");
}
Ok(Some(CurrentTaskInfo { task, .. })) => task,
Err(err) => {
return eprintln!("Cannot read current task: {}", err);
}
};
match args.part {
None => {
if args.clip {
eprintln!("[WARNING]: You don't provide part. --clip option will ignore.");
}
println!("Information about your current task:");
print_task_detail(&task);
}
Some(PrintPart::Project) => {
if args.clip {
if let Some(project) = task.project {
save_to_clipboard(&project);
} else {
eprintln!("Task doesn't contain a project");
}
} else {
println!("{}", task.project.unwrap_or_else(|| String::from('-')))
}
}
Some(PrintPart::DirPath) => {
let dir_path = task
.dir_path
.unwrap_or_else(|| std::env::current_dir().expect("Cannot get current dir"));
if args.clip {
save_to_clipboard(&dir_path.to_string_lossy())
} else {
println!("{}", dir_path.to_string_lossy())
}
}
Some(PrintPart::Link) => {
if let Some(link) = task.link {
if args.clip {
save_to_clipboard(&link);
} else {
println!("{}", link)
}
} else {
eprintln!("The current task doesn't contain link")
}
}
}
}
fn save_to_clipboard(input: &str) {
let xclip_cmd = Command::new("xclip")
.args(["-sel", "clip"])
.stdin(Stdio::piped())
.spawn()
.expect("Cannot spawn xclip command");
let mut xclip_stdin = xclip_cmd.stdin.expect("Cannot get stdin for xclip command");
xclip_stdin
.write_all(input.as_bytes())
.expect("Cannot save data to the clipboard");
}