use std::{ fs::{metadata, read_dir}, path::{Path, PathBuf}, }; use anyhow::Result; use crate::versions::{path_backend::PathVersionBackend, types::VersionBackend}; use crate::versions::archive_backend::ZipVersionBackend; // libarchive backend is Linux-only for now pub mod archive_backend; pub mod path_backend; pub fn _list_files(vec: &mut Vec, path: &Path) -> Result<()> { if metadata(path)?.is_dir() { let paths = read_dir(path)?; for path_result in paths { let full_path = path_result?.path(); if metadata(&full_path)?.is_dir() { _list_files(vec, &full_path)?; } else { vec.push(full_path); } } }; Ok(()) } const SUPPORTED_FILE_EXTENSIONS: [&str; 11] = [ "tar", "pax", "cpio", "zip", "jar", "ar", "xar", "rar", "rpm", "7z", "iso", ]; pub mod types; type BackendConstructor<'a> = Box Result>>; pub fn create_backend_constructor<'a, P>(path: P) -> Option> where P: AsRef, { let path = path.as_ref(); if !path.exists() { return None; } let is_directory = path.is_dir(); if is_directory { let base_dir = path.to_path_buf(); return Some(Box::new(move || { Ok(Box::new(PathVersionBackend { base_dir })) })); }; let file_extension = path.extension().and_then(|v| v.to_str())?; if SUPPORTED_FILE_EXTENSIONS.contains(&file_extension) { let buf = path.to_path_buf(); return Some(Box::new(move || Ok(Box::new(ZipVersionBackend::new(buf)?)))); } None }