mirror of
https://github.com/Llewellynvdm/exa.git
synced 2024-11-05 12:27:53 +00:00
Clean up filetype-detecting code
This commit is contained in:
parent
662aed302a
commit
da49b80c35
21
src/file.rs
21
src/file.rs
@ -25,7 +25,7 @@ use datetime::format::{DateFormat};
|
||||
use column::{Column, Cell};
|
||||
use column::Column::*;
|
||||
use dir::Dir;
|
||||
use filetype::HasType;
|
||||
use filetype::file_type;
|
||||
use options::{SizeFormat, TimeType};
|
||||
use output::details::UserLocale;
|
||||
use feature::Attribute;
|
||||
@ -112,12 +112,6 @@ impl<'a> File<'a> {
|
||||
self.name.starts_with(".")
|
||||
}
|
||||
|
||||
/// Whether this file is a temporary file or not.
|
||||
pub fn is_tmpfile(&self) -> bool {
|
||||
let name = &self.name;
|
||||
name.ends_with("~") || (name.starts_with("#") && name.ends_with("#"))
|
||||
}
|
||||
|
||||
/// Get the data for a column, formatted as a coloured string.
|
||||
pub fn display<U: Users>(&self, column: &Column, users_cache: &mut U, locale: &UserLocale) -> Cell {
|
||||
match *column {
|
||||
@ -207,7 +201,7 @@ impl<'a> File<'a> {
|
||||
|
||||
/// The `ansi_term::Style` that this file's name should be painted.
|
||||
pub fn file_colour(&self) -> Style {
|
||||
self.get_type().style()
|
||||
file_type(&self).style()
|
||||
}
|
||||
|
||||
/// The Unicode 'display width' of the filename.
|
||||
@ -472,6 +466,17 @@ impl<'a> File<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extension_is_one_of(&self, choices: &[&str]) -> bool {
|
||||
match self.ext {
|
||||
Some(ref ext) => choices.contains(&&ext[..]),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name_is_one_of(&self, choices: &[&str]) -> bool {
|
||||
choices.contains(&&self.name[..])
|
||||
}
|
||||
|
||||
fn git_status(&self) -> Cell {
|
||||
let status = match self.dir {
|
||||
None => GREY.paint("--").to_string(),
|
||||
|
207
src/filetype.rs
207
src/filetype.rs
@ -5,54 +5,13 @@ use ansi_term::Style;
|
||||
use ansi_term::Style::Plain;
|
||||
use ansi_term::Colour::{Red, Green, Yellow, Blue, Cyan, Fixed};
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[derive(Debug)]
|
||||
pub enum FileType {
|
||||
Normal, Directory, Executable, Immediate, Compiled, Symlink, Special,
|
||||
Image, Video, Music, Lossless, Compressed, Document, Temp, Crypto,
|
||||
}
|
||||
|
||||
static IMAGE_TYPES: &'static [&'static str] = &[
|
||||
"png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
|
||||
"ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
|
||||
"svg", "stl", "eps", "dvi", "ps", "cbr",
|
||||
"cbz", "xpm", "ico" ];
|
||||
|
||||
static VIDEO_TYPES: &'static [&'static str] = &[
|
||||
"avi", "flv", "m2v", "mkv", "mov", "mp4", "mpeg",
|
||||
"mpg", "ogm", "ogv", "vob", "wmv" ];
|
||||
|
||||
static MUSIC_TYPES: &'static [&'static str] = &[
|
||||
"aac", "m4a", "mp3", "ogg", "wma" ];
|
||||
|
||||
static MUSIC_LOSSLESS: &'static [&'static str] = &[
|
||||
"alac", "ape", "flac", "wav" ];
|
||||
|
||||
static COMPRESSED_TYPES: &'static [&'static str] = &[
|
||||
"zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
|
||||
"iso", "dmg", "tc", "rar", "par" ];
|
||||
|
||||
static DOCUMENT_TYPES: &'static [&'static str] = &[
|
||||
"djvu", "doc", "docx", "dvi", "eml", "eps", "fotd",
|
||||
"odp", "odt", "pdf", "ppt", "pptx", "rtf",
|
||||
"xls", "xlsx" ];
|
||||
|
||||
static TEMP_TYPES: &'static [&'static str] = &[
|
||||
"tmp", "swp", "swo", "swn", "bak" ];
|
||||
|
||||
static CRYPTO_TYPES: &'static [&'static str] = &[
|
||||
"asc", "gpg", "sig", "signature", "pgp" ];
|
||||
|
||||
static COMPILED_TYPES: &'static [&'static str] = &[
|
||||
"class", "elc", "hi", "o", "pyc" ];
|
||||
|
||||
static BUILD_TYPES: &'static [&'static str] = &[
|
||||
"Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
|
||||
"build.gradle", "Rakefile", "Gruntfile.js",
|
||||
"Gruntfile.coffee" ];
|
||||
|
||||
impl FileType {
|
||||
|
||||
/// Get the `ansi_term::Style` that a file of this type should use.
|
||||
pub fn style(&self) -> Style {
|
||||
match *self {
|
||||
Normal => Plain,
|
||||
@ -74,72 +33,115 @@ impl FileType {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait HasType {
|
||||
/// For a given file, find out what type it has.
|
||||
fn get_type(&self) -> FileType;
|
||||
pub fn file_type(file: &File) -> FileType {
|
||||
match file {
|
||||
f if f.is_directory() => Directory,
|
||||
f if f.is_executable_file() => Executable,
|
||||
f if f.is_link() => Symlink,
|
||||
f if !f.is_file() => Special,
|
||||
f if f.is_immediate() => Immediate,
|
||||
f if f.is_image() => Image,
|
||||
f if f.is_video() => Video,
|
||||
f if f.is_music() => Music,
|
||||
f if f.is_lossless() => Lossless,
|
||||
f if f.is_crypto() => Crypto,
|
||||
f if f.is_document() => Document,
|
||||
f if f.is_compressed() => Compressed,
|
||||
f if f.is_temp() => Temp,
|
||||
f if f.is_compiled() => Compiled,
|
||||
_ => Normal,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> HasType for File<'a> {
|
||||
fn get_type(&self) -> FileType {
|
||||
trait FileTypes {
|
||||
fn is_immediate(&self) -> bool;
|
||||
fn is_image(&self) -> bool;
|
||||
fn is_video(&self) -> bool;
|
||||
fn is_music(&self) -> bool;
|
||||
fn is_lossless(&self) -> bool;
|
||||
fn is_crypto(&self) -> bool;
|
||||
fn is_document(&self) -> bool;
|
||||
fn is_compressed(&self) -> bool;
|
||||
fn is_temp(&self) -> bool;
|
||||
fn is_compiled(&self) -> bool;
|
||||
}
|
||||
|
||||
if self.is_directory() {
|
||||
return Directory;
|
||||
}
|
||||
else if self.is_executable_file() {
|
||||
return Executable;
|
||||
}
|
||||
else if self.is_link() {
|
||||
return Symlink;
|
||||
}
|
||||
else if !self.is_file() {
|
||||
return Special;
|
||||
}
|
||||
impl<'_> FileTypes for File<'_> {
|
||||
fn is_immediate(&self) -> bool {
|
||||
self.name.starts_with("README") || self.name_is_one_of( &[
|
||||
"Makefile", "Cargo.toml", "SConstruct", "CMakeLists.txt",
|
||||
"build.gradle", "Rakefile", "Gruntfile.js",
|
||||
"Gruntfile.coffee",
|
||||
])
|
||||
}
|
||||
|
||||
if self.name.starts_with("README") || BUILD_TYPES.contains(&&self.name[..]) {
|
||||
return Immediate;
|
||||
}
|
||||
else if let Some(ref ext) = self.ext {
|
||||
if IMAGE_TYPES.contains(&&ext[..]) {
|
||||
return Image;
|
||||
}
|
||||
else if VIDEO_TYPES.contains(&&ext[..]) {
|
||||
return Video;
|
||||
}
|
||||
else if MUSIC_TYPES.contains(&&ext[..]) {
|
||||
return Music;
|
||||
}
|
||||
else if MUSIC_LOSSLESS.contains(&&ext[..]) {
|
||||
return Lossless;
|
||||
}
|
||||
else if CRYPTO_TYPES.contains(&&ext[..]) {
|
||||
return Crypto;
|
||||
}
|
||||
else if DOCUMENT_TYPES.contains(&&ext[..]) {
|
||||
return Document;
|
||||
}
|
||||
else if COMPRESSED_TYPES.contains(&&ext[..]) {
|
||||
return Compressed;
|
||||
}
|
||||
else if self.is_tmpfile() || TEMP_TYPES.contains(&&ext[..]) {
|
||||
return Temp;
|
||||
}
|
||||
fn is_image(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"png", "jpeg", "jpg", "gif", "bmp", "tiff", "tif",
|
||||
"ppm", "pgm", "pbm", "pnm", "webp", "raw", "arw",
|
||||
"svg", "stl", "eps", "dvi", "ps", "cbr",
|
||||
"cbz", "xpm", "ico",
|
||||
])
|
||||
}
|
||||
|
||||
let source_files = self.get_source_files();
|
||||
if source_files.is_empty() {
|
||||
return Normal;
|
||||
}
|
||||
else if let Some(dir) = self.dir {
|
||||
if source_files.iter().any(|path| dir.contains(path)) {
|
||||
return Temp;
|
||||
}
|
||||
}
|
||||
else if COMPILED_TYPES.contains(&&ext[..]) {
|
||||
return Compiled;
|
||||
}
|
||||
}
|
||||
fn is_video(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"avi", "flv", "m2v", "mkv", "mov", "mp4", "mpeg",
|
||||
"mpg", "ogm", "ogv", "vob", "wmv",
|
||||
])
|
||||
}
|
||||
|
||||
return Normal; // no filetype
|
||||
}
|
||||
fn is_music(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"aac", "m4a", "mp3", "ogg", "wma",
|
||||
])
|
||||
}
|
||||
|
||||
fn is_lossless(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"alac", "ape", "flac", "wav",
|
||||
])
|
||||
}
|
||||
|
||||
fn is_crypto(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
|
||||
"iso", "dmg", "tc", "rar", "par",
|
||||
])
|
||||
}
|
||||
|
||||
fn is_document(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"djvu", "doc", "docx", "dvi", "eml", "eps", "fotd",
|
||||
"odp", "odt", "pdf", "ppt", "pptx", "rtf",
|
||||
"xls", "xlsx",
|
||||
])
|
||||
}
|
||||
|
||||
fn is_compressed(&self) -> bool {
|
||||
self.extension_is_one_of( &[
|
||||
"zip", "tar", "Z", "gz", "bz2", "a", "ar", "7z",
|
||||
"iso", "dmg", "tc", "rar", "par"
|
||||
])
|
||||
}
|
||||
|
||||
fn is_temp(&self) -> bool {
|
||||
self.name.ends_with("~")
|
||||
|| (self.name.starts_with("#") && self.name.ends_with("#"))
|
||||
|| self.extension_is_one_of( &[ "tmp", "swp", "swo", "swn", "bak" ])
|
||||
}
|
||||
|
||||
fn is_compiled(&self) -> bool {
|
||||
if self.extension_is_one_of( &[ "class", "elc", "hi", "o", "pyc" ]) {
|
||||
true
|
||||
}
|
||||
else if let Some(dir) = self.dir {
|
||||
self.get_source_files().iter().any(|path| dir.contains(path))
|
||||
}
|
||||
else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(broken_test)]
|
||||
@ -170,5 +172,4 @@ mod test {
|
||||
let file = new_file(dummy_stat(), "/cargo.toml");
|
||||
assert_eq!(FileType::Normal, file.get_type())
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user