srusty-files 0.2.0

A high-performance, cross-platform file search engine library with REST API
Documentation
use crate::core::types::FileEntry;

pub fn apply_extension_filter(entry: &FileEntry, extensions: &[String]) -> bool {
    if extensions.is_empty() {
        return true;
    }

    if let Some(ref ext) = entry.extension {
        extensions.iter().any(|e| e.eq_ignore_ascii_case(ext))
    } else {
        false
    }
}

pub fn normalize_extension(ext: &str) -> String {
    ext.trim_start_matches('.').to_lowercase()
}

pub fn parse_extensions(input: &str) -> Vec<String> {
    input
        .split(',')
        .map(|s| normalize_extension(s.trim()))
        .filter(|s| !s.is_empty())
        .collect()
}

pub fn is_source_code_extension(ext: &str) -> bool {
    matches!(
        ext.to_lowercase().as_str(),
        "rs" | "py" | "js" | "ts" | "jsx" | "tsx" | "java" | "c" | "cpp" | "cc" | "cxx" | "h"
            | "hpp" | "cs" | "go" | "rb" | "php" | "swift" | "kt" | "scala" | "clj" | "hs"
            | "ml" | "ex" | "exs" | "erl" | "vim" | "lua" | "r" | "sh" | "bash" | "zsh"
            | "fish" | "ps1" | "psm1"
    )
}

pub fn is_document_extension(ext: &str) -> bool {
    matches!(
        ext.to_lowercase().as_str(),
        "txt" | "md" | "pdf" | "doc" | "docx" | "odt" | "rtf" | "tex" | "xls" | "xlsx" | "ods"
            | "ppt" | "pptx" | "odp"
    )
}

pub fn is_image_extension(ext: &str) -> bool {
    matches!(
        ext.to_lowercase().as_str(),
        "jpg" | "jpeg" | "png" | "gif" | "bmp" | "svg" | "webp" | "ico" | "tiff" | "tif"
            | "heic" | "heif"
    )
}

pub fn is_video_extension(ext: &str) -> bool {
    matches!(
        ext.to_lowercase().as_str(),
        "mp4" | "avi" | "mkv" | "mov" | "wmv" | "flv" | "webm" | "m4v" | "mpg" | "mpeg"
    )
}

pub fn is_audio_extension(ext: &str) -> bool {
    matches!(
        ext.to_lowercase().as_str(),
        "mp3" | "wav" | "flac" | "aac" | "ogg" | "wma" | "m4a" | "opus" | "ape"
    )
}

pub fn is_archive_extension(ext: &str) -> bool {
    matches!(
        ext.to_lowercase().as_str(),
        "zip" | "tar" | "gz" | "bz2" | "xz" | "7z" | "rar" | "tgz" | "tbz2" | "txz"
    )
}

pub fn get_extension_category(ext: &str) -> ExtensionCategory {
    if is_source_code_extension(ext) {
        ExtensionCategory::SourceCode
    } else if is_document_extension(ext) {
        ExtensionCategory::Document
    } else if is_image_extension(ext) {
        ExtensionCategory::Image
    } else if is_video_extension(ext) {
        ExtensionCategory::Video
    } else if is_audio_extension(ext) {
        ExtensionCategory::Audio
    } else if is_archive_extension(ext) {
        ExtensionCategory::Archive
    } else {
        ExtensionCategory::Other
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ExtensionCategory {
    SourceCode,
    Document,
    Image,
    Video,
    Audio,
    Archive,
    Other,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_normalize_extension() {
        assert_eq!(normalize_extension(".txt"), "txt");
        assert_eq!(normalize_extension("TXT"), "txt");
        assert_eq!(normalize_extension("rs"), "rs");
    }

    #[test]
    fn test_parse_extensions() {
        let exts = parse_extensions("rs, .txt, .MD");
        assert_eq!(exts, vec!["rs", "txt", "md"]);
    }

    #[test]
    fn test_is_source_code_extension() {
        assert!(is_source_code_extension("rs"));
        assert!(is_source_code_extension("py"));
        assert!(!is_source_code_extension("txt"));
    }

    #[test]
    fn test_get_extension_category() {
        assert_eq!(get_extension_category("rs"), ExtensionCategory::SourceCode);
        assert_eq!(get_extension_category("pdf"), ExtensionCategory::Document);
        assert_eq!(get_extension_category("png"), ExtensionCategory::Image);
        assert_eq!(get_extension_category("mp4"), ExtensionCategory::Video);
        assert_eq!(get_extension_category("mp3"), ExtensionCategory::Audio);
        assert_eq!(get_extension_category("zip"), ExtensionCategory::Archive);
    }
}