fm-tui 0.2.3

FM : a file manager inspired by ranger and dired{n}{n}Config files ~/.config/fm/{n}Documentation https://github.com/qkzk/fm{n}
Documentation
use crate::{
    common::DIR_ICON,
    modes::{extract_extension, FileInfo, FileKind},
};

/// Associate something to a nerdfont icon.
///
/// Those methods require nerdfont to be installed.
pub trait Icon {
    fn icon(&self) -> &'static str;
}

impl Icon for str {
    /// Associate an extension to a nerdfont icon.
    /// Adapted from [ranger_devicons](https://github.com/alexanderjeurissen/ranger_devicons)
    #[inline]
    fn icon(&self) -> &'static str {
        match self {
            "7z" => "",
            "a" => "",
            "ai" => "",
            "apk" => "",
            "asm" => "",
            "asp" => "",
            "aup" => "",
            "avi" => "",
            "awk" => "",
            "bash" => "",
            "bat" => "",
            "bmp" => "",
            "bz2" => "",
            "c" => "",
            "c++" => "",
            "cab" => "",
            "cbr" => "",
            "cbz" => "",
            "cc" => "",
            "class" => "",
            "clj" => "",
            "cljc" => "",
            "cljs" => "",
            "cmake" => "",
            "coffee" => "",
            "conf" => "",
            "cp" => "",
            "cpio" => "",
            "cpp" => "",
            "cs" => "󰌛 ",
            "csh" => "",
            "css" => "",
            "cue" => "",
            "cvs" => "",
            "cxx" => "",
            "d" => "",
            "dart" => "",
            "db" => "",
            "deb" => "",
            "diff" => "",
            "dll" => "",
            "wps" => "",
            "wpt" => "",
            "doc" => "",
            "docx" => "",
            "docm" => "",
            "dotx" => "",
            "dotm" => "",
            "dump" => "",
            "edn" => "",
            "eex" => "",
            "efi" => "",
            "ejs" => "",
            "elf" => "",
            "elm" => "",
            "epub" => "",
            "erl" => "",
            "ex" => "",
            "exe" => "",
            "exs" => "",
            "f#" => "",
            "fifo" => "󰟥 ",
            "fish" => "",
            "flac" => "",
            "flv" => "",
            "fs" => "",
            "fsi" => "",
            "fsscript" => "",
            "fsx" => "",
            "gem" => "",
            "gemspec" => "",
            "gif" => "",
            "go" => "",
            "gz" => "",
            "gzip" => "",
            "h" => "",
            "haml" => "",
            "hbs" => "",
            "hh" => "",
            "hpp" => "",
            "hrl" => "",
            "hs" => "",
            "htaccess" => "",
            "htm" => "",
            "html" => "",
            "htpasswd" => "",
            "hxx" => "",
            "ico" => "",
            "img" => "",
            "ini" => "",
            "ipynb" => "",
            "iso" => "",
            "jar" => "",
            "java" => "",
            "jl" => "",
            "jpeg" => "",
            "jpg" => "",
            "js" => "",
            "json" => "",
            "jsonc" => "",
            "jsx" => "",
            "key" => "",
            "ksh" => "",
            "leex" => "",
            "less" => "",
            "lha" => "",
            "lhs" => "",
            "log" => "",
            "lua" => "",
            "lz" => "",
            "lzh" => "",
            "lzma" => "",
            "m4a" => "",
            "m4v" => "",
            "markdown" => "",
            "md" => "",
            "mdx" => "",
            "mjs" => "",
            "mka" => "",
            "mkv" => "",
            "ml" => "λ ",
            "mli" => "λ ",
            "mov" => "",
            "mp3" => "",
            "mp4" => "",
            "mpeg" => "",
            "mpg" => "",
            "msi" => "",
            "mustache" => "",
            "nix" => "",
            "o" => "",
            "ogg" => "",
            "opus" => "",
            "part" => "",
            "pdf" => "",
            "php" => "",
            "pl" => "",
            "pm" => "",
            "png" => "",
            "pp" => "",
            "dps" => "",
            "dpt" => "",
            "ppt" => "",
            "pptx" => "",
            "pptm" => "",
            "pot" => "",
            "potx" => "",
            "potm" => "",
            "pps" => "",
            "ppsx" => "",
            "ppsm" => "",
            "ps1" => "",
            "psb" => "",
            "psd" => "",
            "pub" => "",
            "py" => "",
            "pyc" => "",
            "pyd" => "",
            "pyo" => "",
            "r" => "󰟔 ",
            "rake" => "",
            "rar" => "",
            "rb" => "",
            "rc" => "",
            "rlib" => "",
            "rmd" => "",
            "rom" => "",
            "rpm" => "",
            "rproj" => "󰗆 ",
            "rs" => "",
            "rss" => "",
            "rtf" => "",
            "s" => "",
            "sass" => "",
            "scala" => "",
            "scss" => "",
            "sh" => "",
            "slim" => "",
            "sln" => "",
            "so" => "",
            "sql" => "",
            "styl" => "",
            "suo" => "",
            "svelte" => "",
            "swift" => "",
            "t" => "",
            "tar" => "",
            "tex" => "󰙩 ",
            "tgz" => "",
            "toml" => "",
            "torrent" => "",
            "ts" => "",
            "tsx" => "",
            "twig" => "",
            "vim" => "",
            "vimrc" => "",
            "vue" => "󰡄 ",
            "wav" => "",
            "webm" => "",
            "webmanifest" => "",
            "webp" => "",
            "xbps" => "",
            "xcplayground" => "",
            "xhtml" => "",
            "et" => "󰈛 ",
            "ett" => "󰈛 ",
            "xls" => "󰈛 ",
            "xlt" => "󰈛 ",
            "xlsx" => "󰈛 ",
            "xlsm" => "󰈛 ",
            "xlsb" => "󰈛 ",
            "xltx" => "󰈛 ",
            "xltm" => "󰈛 ",
            "xla" => "󰈛 ",
            "xlam" => "󰈛 ",
            "xml" => "",
            "xul" => "",
            "xz" => "",
            "yaml" => "",
            "yml" => "",
            "zip" => "",
            "zsh" => "",
            _ => "󰈔 ",
        }
    }
}

impl Icon for std::path::Path {
    /// Icon from a path.
    /// Should only be used in tree display.
    /// Requires metadata and is quite heavy.
    fn icon(&self) -> &'static str {
        let Ok(metadata) = self.symlink_metadata() else {
            return DIR_ICON;
        };
        let file_kind = FileKind::new(&metadata, self);
        match file_kind {
            FileKind::NormalFile => extract_extension(self).icon(),
            _ => file_kind.icon(),
        }
    }
}

impl Icon for FileKind<bool> {
    /// Icon per file kind.
    /// Shouldn't be called for normal files, use extension.icon() directly.
    fn icon(&self) -> &'static str {
        match self {
            Self::Fifo => "",
            Self::Socket => "󰟩 ",
            Self::Directory => DIR_ICON,
            Self::NormalFile => "",
            Self::CharDevice => "",
            Self::BlockDevice => "",
            Self::SymbolicLink(_) => "",
        }
    }
}

impl Icon for FileInfo {
    /// Icon for a file given by its fileinfo.
    fn icon(&self) -> &'static str {
        match self.file_kind {
            FileKind::NormalFile => self.extension.icon(),
            _ => self.file_kind.icon(),
        }
    }
}