dialogs: use `Cow<str>` to avoid cloning a String
[ouch.git] / src / extension.rs
blob05328319d447622714cbb9aa1a0c89e1e094196c
1 use std::{fmt, path::Path};
3 use CompressionFormat::*;
5 #[derive(Clone, PartialEq, Eq, Debug)]
6 /// Accepted extensions for input and output
7 pub enum CompressionFormat {
8     Gzip, // .gz
9     Bzip, // .bz
10     Lzma, // .lzma
11     Tar,  // .tar (technically not a compression extension, but will do for now)
12     Zip,  // .zip
15 impl fmt::Display for CompressionFormat {
16     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
17         write!(
18             f,
19             "{}",
20             match self {
21                 Gzip => ".gz",
22                 Bzip => ".bz",
23                 Lzma => ".lz",
24                 Tar => ".tar",
25                 Zip => ".zip",
26             }
27         )
28     }
31 pub fn separate_known_extensions_from_name(mut path: &Path) -> (&Path, Vec<CompressionFormat>) {
32     // // TODO: check for file names with the name of an extension
33     // // TODO2: warn the user that currently .tar.gz is a .gz file named .tar
34     //
35     // let all = ["tar", "zip", "bz", "bz2", "gz", "xz", "lzma", "lz"];
36     // if path.file_name().is_some() && all.iter().any(|ext| path.file_name().unwrap() == *ext) {
37     //     todo!("we found a extension in the path name instead, what to do with this???");
38     // }
40     let mut extensions = vec![];
42     // While there is known extensions at the tail, grab them
43     while let Some(extension) = path.extension() {
44         let extension = match () {
45             _ if extension == "tar" => Tar,
46             _ if extension == "zip" => Zip,
47             _ if extension == "bz" => Bzip,
48             _ if extension == "gz" || extension == "bz2" => Gzip,
49             _ if extension == "xz" || extension == "lzma" || extension == "lz" => Lzma,
50             _ => break,
51         };
53         extensions.push(extension);
55         // Update for the next iteration
56         path = if let Some(stem) = path.file_stem() { Path::new(stem) } else { Path::new("") };
57     }
58     // Put the extensions in the correct order: left to right
59     extensions.reverse();
61     (path, extensions)
64 pub fn extensions_from_path(path: &Path) -> Vec<CompressionFormat> {
65     let (_, extensions) = separate_known_extensions_from_name(path);
66     extensions