use std::collections::HashSet;
use crate::{errors::FileIgnoreError, ext, min::Minifier};
#[derive(Clone)]
pub enum FileOp {
Pass,
Recompress(u8),
Minify(Minifier),
Ignore(FileIgnoreError),
}
impl FileOp {
pub(crate) fn by_name(fname: &str, blacklist: &TypeBlacklist) -> Self {
if fname.starts_with(".cache/") { return Self::Ignore(FileIgnoreError::Blacklisted) }
if let Some(sub) = fname.strip_prefix("META-INF/") {
match sub {
"SIGNFILE.SF" | "SIGNFILE.DSA" => { return Self::Ignore(FileIgnoreError::Signfile) }
x if x.starts_with("SIG-") || [".DSA", ".RSA", ".SF"].into_iter().any(|e| x.ends_with(e)) => {
return Self::Ignore(FileIgnoreError::Signfile)
}
x if x.starts_with("services/") => { return Self::Recompress(64) }
_ => {}
}
}
let Some((_, ftype)) = fname.rsplit_once('.') else {
return Self::Pass
};
if blacklist.can_ignore(ftype) {
return Self::Ignore(FileIgnoreError::Blacklisted)
}
ext::KnownFmt::by_extension(ftype)
.map_or(Self::Pass, |x| Minifier::by_file_format(x).map_or(Self::Pass, Self::Minify))
}
}
pub enum TypeBlacklist {
Extend(Option<HashSet<Box<str>>>),
Override(Option<HashSet<Box<str>>>)
}
impl TypeBlacklist {
fn can_ignore(&self, s: &str) -> bool {
let inner = match self {
Self::Extend(x) => {
if matches!(s, "bak" | "blend" | "blend1" | "disabled" | "gitignore" | "gitkeep" | "lnk" | "old" | "pdn" | "psd" | "xcf") {
return true
}
x
}
Self::Override(x) => x
};
inner.as_ref().map_or(false, |x| x.contains(s))
}
}