use std::io::BufRead;
use std::path::{Path, PathBuf};
use std::{fs::File, io::BufReader};
use anyhow::Context;
use crate::helper::types::OutputFmt;
use flate2::read::MultiGzDecoder;
pub fn is_gzip(path: &Path) -> bool {
path.extension()
.and_then(|ext| ext.to_str())
.map(|ext| ext.eq_ignore_ascii_case("gz") || ext.eq_ignore_ascii_case("gzip"))
.unwrap_or(false)
}
pub fn open_reader(path: &Path) -> anyhow::Result<Box<dyn BufRead + Send>> {
let file = File::open(path).with_context(|| format!("Failed opening {}", path.display()))?;
if is_gzip(path) {
Ok(Box::new(BufReader::new(MultiGzDecoder::new(file))))
} else {
Ok(Box::new(BufReader::new(file)))
}
}
pub fn decode_gzip(path: &Path) -> BufReader<MultiGzDecoder<File>> {
let file = File::open(path).expect("Failed to open file");
let decoder = MultiGzDecoder::new(file);
BufReader::new(decoder)
}
pub fn open_file(path: &Path) -> BufReader<File> {
let file = File::open(path).expect("Failed opening a file");
BufReader::new(file)
}
pub fn create_output_fname(dir: &Path, file: &Path, output_fmt: &OutputFmt) -> PathBuf {
let path = dir.join(
file.file_name()
.expect("Failed parsing filename for output file"),
);
create_output_fname_from_path(&path, output_fmt)
}
pub fn create_output_fname_from_stem(dir: &Path, stem: &str, output_fmt: &OutputFmt) -> PathBuf {
dir.join(format!("{}.{}", stem, output_extension(output_fmt)))
}
pub fn output_extension(output_fmt: &OutputFmt) -> &'static str {
match output_fmt {
OutputFmt::Fasta | OutputFmt::FastaInt => "fas",
OutputFmt::Nexus | OutputFmt::NexusInt => "nex",
OutputFmt::Phylip | OutputFmt::PhylipInt => "phy",
}
}
pub fn create_output_fname_for_text(dir: &Path, prefix: &Path) -> PathBuf {
dir.join(prefix.with_extension("txt"))
}
pub fn create_output_fname_from_path(path: &Path, output_fmt: &OutputFmt) -> PathBuf {
path.with_extension(output_extension(output_fmt))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_create_output_fname() {
let path = Path::new("tests/test_create_output_fname.nex");
let dir = Path::new("tests");
assert_eq!(
create_output_fname(dir, path, &OutputFmt::Fasta),
Path::new("tests/test_create_output_fname.fas")
);
}
#[test]
fn test_is_gzip() {
assert!(is_gzip(Path::new("a.maf.gz")));
assert!(is_gzip(Path::new("a.BED.GZ")));
assert!(is_gzip(Path::new("a.gzip")));
assert!(!is_gzip(Path::new("a.maf")));
assert!(!is_gzip(Path::new("gz")));
}
#[test]
fn test_output_fname_from_stem_keeps_dots() {
let output = create_output_fname_from_stem(Path::new("out"), "a.b", &OutputFmt::Nexus);
assert_eq!(output, Path::new("out").join("a.b.nex"));
}
}