deep_unpack/formats/
kinds.rs1use std::path::Path;
3
4use anyhow::Result;
5use lazy_static::lazy_static;
6use regex::Regex;
7
8use crate::formats::zip::ZipArchive;
9
10lazy_static! {
11 static ref BY_PATTERN: Vec<(Regex, ArchiveKind)> = vec![
12 (Regex::new(r"(?i)\.zip$").unwrap(), ArchiveKind::Zip),
13 (Regex::new(r"(?i)\.jar$").unwrap(), ArchiveKind::Zip)
14 ];
15}
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq)]
18pub enum ArchiveKind {
19 Zip,
20}
21
22pub trait Archive {
23 fn path(&self) -> &Path;
24
25 fn unpack(&mut self, path: &Path) -> Result<()>;
26}
27
28impl ArchiveKind {
29 #[must_use]
31 pub fn for_path(path: &Path) -> Option<Self> {
32 Self::determine_by_filename(path)
33 }
34
35 fn determine_by_filename(path: &Path) -> Option<Self> {
37 if let Some(filename) = path.file_name().and_then(std::ffi::OsStr::to_str) {
38 for &(ref regex, ty) in BY_PATTERN.iter() {
39 if regex.is_match(filename) {
40 return Some(ty);
41 }
42 }
43 };
44 None
45 }
46
47 #[allow(clippy::new_ret_no_self)]
49 #[must_use]
50 pub fn new(self, path: &Path) -> Box<dyn Archive> {
51 match self {
52 Self::Zip => Box::new(ZipArchive::new(path)),
53 }
54 }
55}