1use std::fs::{File, OpenOptions};
2use std::path::PathBuf;
3
4use anyhow::{Context, Result};
5
6use duct::cmd;
7use tempfile::{NamedTempFile, Builder};
8
9#[cfg(not(windows))]
10pub fn command_exists(cmd: &str) -> bool {
11 let output = cmd!("which", cmd)
12 .read()
13 .unwrap_or_else(|_| String::new());
14
15 !output.trim().is_empty()
16}
17
18pub fn open_file_with_mode(path: &str) -> Result<File> {
19 let mut options = OpenOptions::new();
20 options.write(true).create(true);
21
22 let (mode, clean_path) = if let Some(s) = path.strip_prefix('+') {
23 (true, s)
24 } else {
25 (false, path)
26 };
27
28 if mode {
29 options.append(true);
30 } else {
31 options.truncate(true);
32 }
33
34 let file = options.open(clean_path)
35 .with_context(|| format!("Failed to open file: {}", clean_path))?;
36
37 Ok(file)
38}
39
40pub fn create_temp_file(tempdir_placeholder: &Option<&str>) -> Result<PathBuf> {
41 let temp_file = if let Some(dir) = tempdir_placeholder {
42 Builder::new().prefix("tempfile").tempfile_in(dir)?
43 } else {
44 NamedTempFile::new()?
45 };
46
47 Ok(temp_file.path().to_path_buf())
48}