1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use anyhow::Result;
use flate2::read;
use flate2::Compression;
use gzp::deflate::Bgzf;
use gzp::ZBuilder;
use std::ffi::OsStr;
use std::fs::File;
use std::io::{self, BufRead, BufReader, BufWriter, Write};
use std::path::Path;
use std::path::PathBuf;
const BUFFER_SIZE: usize = 128 * 1024;
pub fn writer(filename: &str) -> Box<dyn Write> {
let ext = Path::new(filename).extension();
let path = PathBuf::from(filename);
let buffer = get_output(Some(path)).expect("Error: cannot create output file");
if ext == Some(OsStr::new("gz")) {
let writer = ZBuilder::<Bgzf, _>::new()
.num_threads(8)
.compression_level(Compression::new(6))
.from_writer(buffer);
Box::new(writer)
} else {
buffer
}
}
pub fn reader(filename: &str) -> Box<dyn BufRead> {
let ext = Path::new(filename).extension();
let path = PathBuf::from(filename);
if ext == Some(OsStr::new("gz")) {
let file = match File::open(&path) {
Err(why) => panic!("couldn't open {}: {}", path.display(), why.to_string()),
Ok(file) => file,
};
Box::new(BufReader::with_capacity(
BUFFER_SIZE,
read::GzDecoder::new(file),
))
} else {
get_input(Some(path)).expect("Error: cannot read input file")
}
}
pub fn get_output(path: Option<PathBuf>) -> Result<Box<dyn Write + Send + 'static>> {
let writer: Box<dyn Write + Send + 'static> = match path {
Some(path) => {
if path.as_os_str() == "-" {
Box::new(BufWriter::with_capacity(BUFFER_SIZE, io::stdout()))
} else {
Box::new(BufWriter::with_capacity(BUFFER_SIZE, File::create(path)?))
}
}
None => Box::new(BufWriter::with_capacity(BUFFER_SIZE, io::stdout())),
};
Ok(writer)
}
pub fn get_input(path: Option<PathBuf>) -> Result<Box<dyn BufRead + Send + 'static>> {
let reader: Box<dyn BufRead + Send + 'static> = match path {
Some(path) => {
if path.as_os_str() == "-" {
Box::new(BufReader::with_capacity(BUFFER_SIZE, io::stdin()))
} else {
Box::new(BufReader::with_capacity(BUFFER_SIZE, File::open(path)?))
}
}
None => Box::new(BufReader::with_capacity(BUFFER_SIZE, io::stdin())),
};
Ok(reader)
}