use std::collections::HashSet;
use std::sync::LazyLock;
use crate::extensions;
use crate::interpreters;
pub const DIRECTORY: &str = "directory";
pub const SYMLINK: &str = "symlink";
pub const SOCKET: &str = "socket";
pub const FILE: &str = "file";
pub const EXECUTABLE: &str = "executable";
pub const NON_EXECUTABLE: &str = "non-executable";
pub const TEXT: &str = "text";
pub const BINARY: &str = "binary";
pub type TagSet = HashSet<&'static str>;
#[inline]
pub fn tags_from_array(tags: &[&'static str]) -> TagSet {
tags.iter().copied().collect()
}
pub static TYPE_TAGS: LazyLock<TagSet> =
LazyLock::new(|| HashSet::from([DIRECTORY, FILE, SYMLINK, SOCKET]));
pub static MODE_TAGS: LazyLock<TagSet> =
LazyLock::new(|| HashSet::from([EXECUTABLE, NON_EXECUTABLE]));
pub static ENCODING_TAGS: LazyLock<TagSet> = LazyLock::new(|| HashSet::from([BINARY, TEXT]));
pub fn is_type_tag(tag: &str) -> bool {
matches!(tag, DIRECTORY | FILE | SYMLINK | SOCKET)
}
pub fn is_mode_tag(tag: &str) -> bool {
matches!(tag, EXECUTABLE | NON_EXECUTABLE)
}
pub fn is_encoding_tag(tag: &str) -> bool {
matches!(tag, BINARY | TEXT)
}
pub static ALL_TAGS: LazyLock<TagSet> = LazyLock::new(|| {
let mut tags = TagSet::new();
tags.extend(TYPE_TAGS.iter());
tags.extend(MODE_TAGS.iter());
tags.extend(ENCODING_TAGS.iter());
for entry in extensions::EXTENSION_TAGS.values() {
tags.extend(entry.iter().copied());
}
for entry in extensions::EXTENSIONS_NEED_BINARY_CHECK_TAGS.values() {
tags.extend(entry.iter().copied());
}
for entry in extensions::NAME_TAGS.values() {
tags.extend(entry.iter().copied());
}
for entry in interpreters::INTERPRETER_TAGS.values() {
tags.extend(entry.iter().copied());
}
tags
});
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FileKind {
Regular,
Directory,
Symlink,
Socket,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_all_tags_contains_basics() {
assert!(ALL_TAGS.contains("file"));
assert!(ALL_TAGS.contains("directory"));
assert!(ALL_TAGS.contains("executable"));
assert!(ALL_TAGS.contains("non-executable"));
assert!(ALL_TAGS.contains("text"));
assert!(ALL_TAGS.contains("binary"));
assert!(ALL_TAGS.contains("python"));
assert!(ALL_TAGS.contains("rust"));
assert!(ALL_TAGS.contains("javascript"));
assert!(ALL_TAGS.contains("json"));
assert!(ALL_TAGS.contains("shell"));
assert!(ALL_TAGS.contains("ruby"));
assert!(ALL_TAGS.contains("perl"));
}
#[test]
fn test_all_tags_does_not_contain_garbage() {
assert!(!ALL_TAGS.contains("notarealtag"));
}
}