1 extern crate clap;
2 extern crate libflate;
3 
4 use clap::App;
5 use clap::Arg;
6 use clap::SubCommand;
7 use libflate::gzip;
8 use libflate::zlib;
9 use std::fs;
10 use std::io;
11 use std::io::Read;
12 use std::io::Write;
13 use std::process;
14 
main()15 fn main() {
16     let matches = App::new("deflate")
17         .arg(
18             Arg::with_name("INPUT")
19                 .short("i")
20                 .long("input")
21                 .value_name("FILE")
22                 .takes_value(true)
23                 .default_value("-"),
24         )
25         .arg(
26             Arg::with_name("OUTPUT")
27                 .short("o")
28                 .long("output")
29                 .value_name("FILE")
30                 .takes_value(true)
31                 .default_value("-"),
32         )
33         .arg(Arg::with_name("VERBOSE").short("v").long("verbose"))
34         .subcommand(SubCommand::with_name("copy"))
35         .subcommand(
36             SubCommand::with_name("byte-read").arg(
37                 Arg::with_name("UNIT")
38                     .short("u")
39                     .long("unit")
40                     .takes_value(true)
41                     .default_value("1"),
42             ),
43         )
44         .subcommand(SubCommand::with_name("gzip-decode"))
45         .subcommand(SubCommand::with_name("gzip-decode-multi"))
46         .subcommand(SubCommand::with_name("gzip-encode"))
47         .subcommand(SubCommand::with_name("zlib-decode"))
48         .subcommand(SubCommand::with_name("zlib-encode"))
49         .get_matches();
50 
51     let input_filename = matches.value_of("INPUT").unwrap();
52     let input: Box<dyn io::Read> = if input_filename == "-" {
53         Box::new(io::stdin())
54     } else {
55         Box::new(
56             fs::File::open(input_filename).expect(&format!("Can't open file: {}", input_filename)),
57         )
58     };
59     let mut input = io::BufReader::new(input);
60 
61     let output_filename = matches.value_of("OUTPUT").unwrap();
62     let output: Box<dyn io::Write> = if output_filename == "-" {
63         Box::new(io::stdout())
64     } else if output_filename == "/dev/null" {
65         Box::new(io::sink())
66     } else {
67         Box::new(
68             fs::File::create(output_filename)
69                 .expect(&format!("Can't create file: {}", output_filename)),
70         )
71     };
72     let mut output = io::BufWriter::new(output);
73 
74     let verbose = matches.is_present("VERBOSE");
75     if let Some(_matches) = matches.subcommand_matches("copy") {
76         io::copy(&mut input, &mut output).expect("Coyping failed");
77     } else if let Some(matches) = matches.subcommand_matches("byte-read") {
78         let unit = matches
79             .value_of("UNIT")
80             .and_then(|x| x.parse::<usize>().ok())
81             .unwrap();
82         let mut buf = vec![0; unit];
83         let mut reader = input;
84         let mut count = 0;
85         while let Ok(size) = reader.read(&mut buf) {
86             if size == 0 {
87                 break;
88             }
89             count += size;
90         }
91         println!("COUNT: {}", count);
92     } else if let Some(_matches) = matches.subcommand_matches("gzip-decode") {
93         let mut decoder = gzip::Decoder::new(input).expect("Read GZIP header failed");
94         if verbose {
95             let _ = writeln!(&mut io::stderr(), "HEADER: {:?}", decoder.header());
96         }
97         io::copy(&mut decoder, &mut output).expect("Decoding GZIP stream failed");
98     } else if let Some(_matches) = matches.subcommand_matches("gzip-decode-multi") {
99         let mut decoder = gzip::MultiDecoder::new(input).expect("Read GZIP header failed");
100         io::copy(&mut decoder, &mut output).expect("Decoding GZIP stream failed");
101     } else if let Some(_matches) = matches.subcommand_matches("gzip-encode") {
102         let mut encoder = gzip::Encoder::new(output).unwrap();
103         io::copy(&mut input, &mut encoder).expect("Encoding GZIP stream failed");
104         encoder.finish().into_result().unwrap();
105     } else if let Some(_matches) = matches.subcommand_matches("zlib-decode") {
106         let mut decoder = zlib::Decoder::new(input).expect("Read ZLIB header failed");
107         if verbose {
108             let _ = writeln!(&mut io::stderr(), "HEADER: {:?}", decoder.header());
109         }
110         io::copy(&mut decoder, &mut output).expect("Decoding ZLIB stream failed");
111     } else if let Some(_matches) = matches.subcommand_matches("zlib-encode") {
112         let mut encoder = zlib::Encoder::new(output).unwrap();
113         io::copy(&mut input, &mut encoder).expect("Encoding ZLIB stream failed");
114         encoder.finish().into_result().unwrap();
115     } else {
116         println!("{}", matches.usage());
117         process::exit(1);
118     }
119 }
120