use serde::Deserialize;
use std::ffi::OsString;
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, ExitStatus};
use which::which;
pub fn check_readable_file(path: &Path) -> Result<&Path, String> {
if !path.is_file() {
return Err("cannot read file.".to_string());
}
Ok(path)
}
#[derive(Deserialize)]
pub struct FilesConfig {
pub files: Vec<String>,
}
pub struct FilePair {
pub enc_name: String,
pub dec_name: String,
}
pub fn load_files_config(path: &Path) -> Result<FilesConfig, String> {
let path = check_readable_file(path)?;
let contents = match fs::read_to_string(path) {
Ok(contents) => contents,
Err(err) => return Err(format!("failed to read file: {}", err)),
};
match toml::from_str(&contents) {
Ok(config) => Ok(config),
Err(err) => return Err(format!("failed to decode TOML: {}", err)),
}
}
pub fn find_sops(binary_name: &str) -> Result<PathBuf, String> {
match which(binary_name) {
Ok(b) => Ok(b),
Err(err) => return Err(format!("could not find sops binary: {}", err)),
}
}
pub fn call_sops(sops_bin: &Path, args: Vec<&str>, verbose: bool) -> Result<ExitStatus, String> {
if verbose {
eprintln!("calling sops: {} {}", sops_bin.display(), args.join(" "));
}
let mut c = match Command::new(sops_bin).args(args).spawn() {
Ok(c) => c,
Err(err) => return Err(format!("sops call failed: {}", err)),
};
match c.wait() {
Ok(s) => Ok(s),
Err(err) => return Err(format!("sops call failed: {}", err)),
}
}
impl FilePair {
pub fn from_filename(filename: &str) -> FilePair {
let enc_name;
let dec_name;
if filename.contains(".enc") {
enc_name = filename.to_string();
dec_name = enc_name.replace(".enc", "");
} else {
dec_name = filename.to_string();
let path = match Path::new(&dec_name).parent() {
Some(path) => path.to_owned(),
None => Path::new("").to_owned(),
};
let filestem = match Path::new(&dec_name).file_stem() {
Some(stem) => stem.to_owned(),
None => OsString::from(""),
};
let ext = match Path::new(&dec_name).extension() {
Some(ext) => format!("enc.{}", ext.to_str().unwrap()),
None => OsString::from("enc").to_str().unwrap().to_owned(),
};
let new_parent = PathBuf::from(path);
let mut new_name = PathBuf::new();
new_name.set_file_name(filestem);
new_name.set_extension(ext);
enc_name = new_parent.join(new_name).to_str().unwrap().to_owned();
}
FilePair { enc_name, dec_name }
}
}