Skip to main content

anycat/
lib.rs

1extern crate flate2;
2extern crate bzip2;
3extern crate xz2;
4extern crate brotli2;
5
6use std::fs::File;
7use std::io::{BufRead, BufReader};
8
9use flate2::read::*;
10use bzip2::read::*;
11use xz2::read::*;
12use brotli2::read::*;
13
14/// Returns a BufRead to the file denoted by the given fname. The stream is possibly decompressed
15/// using the following scheme. Depending on the **file extension**, the following algorithm is
16/// used:
17/// - .gz, .gzip  ===> GZIP
18/// - .z , .zlib  ===> ZLIB
19/// - .dfl        ===> DEFLATE
20/// - .bz2, .bzip ===> BZ2
21/// - .xz2, .lzma ===> LZMA (xz2)
22/// - .br , .brotli => BROTLI
23///
24/// Otherwise, the file is assumed to contain plaintext and is treated as such
25pub fn readfile(fname: &str) -> Result<Box<dyn BufRead + Send>, std::io::Error> {
26    let file = File::open(fname)?;
27
28    let canonical = fname.to_lowercase();
29
30    // I'm sure about these ones
31    if canonical.ends_with(".gz") || canonical.ends_with(".gzip") {
32        return Ok(Box::new(BufReader::new(GzDecoder::new(file))));
33    }
34    if canonical.ends_with(".bz2") || canonical.ends_with(".bzip") {
35        return Ok(Box::new(BufReader::new(BzDecoder::new(file))));
36    }
37    if canonical.ends_with(".xz") || canonical.ends_with(".lzma") {
38        return Ok(Box::new(BufReader::new(XzDecoder::new(file))));
39    }
40
41    // I *guess* about these ones...
42    if canonical.ends_with(".zlib") || canonical.ends_with(".z") {
43        return Ok(Box::new(BufReader::new(ZlibDecoder::new(file))));
44    }
45    if canonical.ends_with(".dfl") {
46        return Ok(Box::new(BufReader::new(DeflateDecoder::new(file))));
47    }
48    if canonical.ends_with(".brotli") || canonical.ends_with(".br") {
49        return Ok(Box::new(BufReader::new(BrotliDecoder::new(file))));
50    }
51
52    return Ok(Box::new(BufReader::new(file)));
53}