1#[macro_use] extern crate failure; use failure::Error;
2#[macro_use] extern crate log;
3
4extern crate zip as zipcrate;
5extern crate xz2;
6extern crate flate2;
7extern crate tar as tarcrate;
8
9#[cfg(feature = "indicate")]
10extern crate indicatif;
11
12use std::path::{PathBuf, Path};
13use std::fs;
14
15mod formats;
16
17pub fn contains_file<P:AsRef<Path>>(src : P, file : &str) -> Result<bool,Error>
18 where std::path::PathBuf: std::convert::From<P>, P : std::fmt::Display + Copy,
19{
20 let src_path : PathBuf = PathBuf::from(src);
23
24 match src_path.extension() {
25 None => Err(format_err!("File '{}' has no extension, not a file?",src)),
26 Some(ext) => {
27 match ext.to_str().unwrap() {
28 "zip" => formats::zip::contains(&src_path,file),
29 "tar" => formats::tar::contains(&src_path,file),
30 "gz" => {
31 let buffer = formats::gz::decode(&src_path)?;
32 match get_second_extension(src_path.file_name().unwrap().to_str().unwrap()){
33 Some("tar") => formats::tar::buffer_contains(&buffer,file),
34 Some(other_ext) => Err(format_err!("Unknown format {}",other_ext)),
35 None => Err(format_err!("No nested archive")),
36 }
37 },
38 "xz" => {
39 let buffer = formats::xz::decode(&src_path)?;
40 match get_second_extension(src_path.file_name().unwrap().to_str().unwrap()){
41 Some("tar") => formats::tar::buffer_contains(&buffer,file),
42 Some(other_ext) => Err(format_err!("Unknown format {}",other_ext)),
43 None => Err(format_err!("No nested archive")),
44 }
45 },
46 ext => Err(format_err!("Unknown extension type {}",ext)),
47 }
48 }
49 }
50}
51
52pub fn extract_to<P:AsRef<Path>>(src : P, des : P) -> Result<PathBuf,Error>
53 where std::path::PathBuf: std::convert::From<P>, P : std::fmt::Display + Copy,
54{
55 let src_path : PathBuf = PathBuf::from(src);
62 let des_path : PathBuf = PathBuf::from(des);
63
64 if false == src_path.exists() {
65 return Err(format_err!("Source file, '{}' does not exist.",src));
66 }
67
68 if false == des_path.exists() {
69 warn!("Destination '{}' does not exist.",src);
70 fs::create_dir_all(&des_path)?;
71 }
72
73 match src_path.extension() {
74 None => Err(format_err!("File '{}' has no extension, not a file?",src)),
75 Some(ext) => {
76 match ext.to_str().unwrap() {
77 "zip" => formats::zip::extract(&src_path,&des_path),
78 "tar" => formats::tar::extract(&src_path,&des_path),
79 "gz" => {
80 let buffer = formats::gz::decode(&src_path)?;
81 match get_second_extension(src_path.file_name().unwrap().to_str().unwrap()){
82 Some("tar") => formats::tar::extract_buffer(&buffer,&des_path,false),
83 Some(other_ext) => Err(format_err!("Unknown format {}",other_ext)),
84 None => Err(format_err!("No nested archive")),
85 }
86 },
87 "xz" => {
88 let buffer = formats::xz::decode(&src_path)?;
89 match get_second_extension(src_path.file_name().unwrap().to_str().unwrap()){
90 Some("tar") => formats::tar::extract_buffer(&buffer,&des_path,false),
91 Some(other_ext) => Err(format_err!("Unknown format {}",other_ext)),
92 None => Err(format_err!("No nested archive")),
93 }
94 },
95 ext => Err(format_err!("Unknown extension type {}",ext)),
96 }
97 }
98 }
99}
100
101
102pub fn extract_root_to<P:AsRef<Path>>(src : P, des : P) -> Result<PathBuf,Error>
103 where std::path::PathBuf: std::convert::From<P>, P : std::fmt::Display + Copy,
104{
105 let src_path : PathBuf = PathBuf::from(src);
121 let des_path : PathBuf = PathBuf::from(des);
122
123 if false == src_path.exists() {
124 return Err(format_err!("Source file, '{}' does not exist.",src));
125 }
126
127 if false == des_path.exists() {
128 warn!("Destination '{}' does not exist.",src);
129 fs::create_dir_all(&des_path)?;
130 }
131
132 match src_path.extension() {
133 None => Err(format_err!("File '{}' has no extension, not a file?",src)),
134 Some(ext) => {
135 match ext.to_str().unwrap() {
136 "zip" => formats::zip::extract_root(&src_path,&des_path),
137 "tar" => formats::tar::extract_root(&src_path,&des_path),
138 "gz" => {
139 let buffer = formats::gz::decode(&src_path)?;
140 match get_second_extension(src_path.file_name().unwrap().to_str().unwrap()){
141 Some("tar") => formats::tar::extract_buffer(&buffer,&des_path,true),
142 Some(other_ext) => Err(format_err!("Unknown format {}",other_ext)),
143 None => Err(format_err!("No nested archive")),
144 }
145 },
146 "xz" => {
147 let buffer = formats::xz::decode(&src_path)?;
148 match get_second_extension(src_path.file_name().unwrap().to_str().unwrap()){
149 Some("tar") => formats::tar::extract_buffer(&buffer,&des_path,true),
150 Some(other_ext) => Err(format_err!("Unknown format {}",other_ext)),
151 None => Err(format_err!("No nested archive")),
152 }
153 },
154 ext => Err(format_err!("Unknown extension type {}",ext)),
155 }
156 }
157 }
158}
159
160fn get_second_extension<'a>(file : &'a str) -> Option<&'a str> {
161 let splits = file.split(".").collect::<Vec<&str>>();
164
165 if splits.len() >= 3 {
166 Some(splits[splits.len()-2])
167 } else {
168 None
169 }
170}