From a60ab3d3e402428922f1fd826abffe6be986e573 Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Sun, 31 Jul 2022 17:06:30 +0800 Subject: [PATCH] :hammer: icon: refactor to use icon by file type --- src/core.rs | 7 ++---- src/flags/icons.rs | 2 +- src/icon.rs | 32 +++++++++++------------ src/theme.rs | 12 +-------- src/theme/icon.rs | 63 +++++++++++++++++++++++++++++++++++++++------- 5 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/core.rs b/src/core.rs index 59bbf13..9377c07 100644 --- a/src/core.rs +++ b/src/core.rs @@ -1,10 +1,7 @@ use crate::color::Colors; use crate::display; -use crate::flags::{ - ColorOption, Display, Flags, HyperlinkOption, IconOption, IconTheme, Layout, SortOrder, - ThemeOption, -}; -use crate::icon::{self, Icons}; +use crate::flags::{ColorOption, Display, Flags, HyperlinkOption, Layout, SortOrder, ThemeOption}; +use crate::icon::Icons; use crate::meta::Meta; use crate::{print_error, print_output, sort, ExitCode}; use std::path::PathBuf; diff --git a/src/flags/icons.rs b/src/flags/icons.rs index 084d97a..638c92e 100644 --- a/src/flags/icons.rs +++ b/src/flags/icons.rs @@ -90,7 +90,7 @@ impl Configurable for IconOption { } /// The flag showing which icon theme to use. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum IconTheme { Unicode, diff --git a/src/icon.rs b/src/icon.rs index dd3b9a8..cb8b4f9 100644 --- a/src/icon.rs +++ b/src/icon.rs @@ -36,34 +36,34 @@ impl Icons { // Check file types let file_type: FileType = name.file_type(); let icon = match file_type { - FileType::SymLink { is_dir: true } => "\u{f482}", // "" - FileType::SymLink { is_dir: false } => "\u{f481}", // "" - FileType::Socket => "\u{f6a7}", // "" - FileType::Pipe => "\u{f731}", // "" - FileType::CharDevice => "\u{e601}", // "" - FileType::BlockDevice => "\u{fc29}", // "ﰩ" - FileType::Special => "\u{f2dc}", // "" + FileType::SymLink { is_dir: true } => &t.icons_by_filetype.symlink_dir, + FileType::SymLink { is_dir: false } => &t.icons_by_filetype.symlink_file, + FileType::Socket => &t.icons_by_filetype.socket, + FileType::Pipe => &t.icons_by_filetype.pipe, + FileType::CharDevice => &t.icons_by_filetype.device_char, + FileType::BlockDevice => &t.icons_by_filetype.device_block, + FileType::Special => &t.icons_by_filetype.special, _ => { - // Use the known names if let Some(icon) = t .icons_by_name .get(name.file_name().to_lowercase().as_str()) { icon - } - // Use the known extensions - else if let Some(icon) = name.extension().and_then(|extension| { - t.icons_by_extension.get(extension.to_lowercase().as_str()) - }) { + } else if let Some(icon) = name + .extension() + .and_then(|ext| t.icons_by_extension.get(ext.to_lowercase().as_str())) + { icon } else { match file_type { - FileType::Directory { .. } => &t.default_folder_icon, + FileType::Directory { .. } => &t.icons_by_filetype.dir, // If a file has no extension and is executable, show an icon. // Except for Windows, it marks everything as an executable. #[cfg(not(windows))] - FileType::File { exec: true, .. } => "\u{f489}", // "" - _ => &t.default_file_icon, + FileType::File { exec: true, .. } => { + &t.icons_by_filetype.executable + } + _ => &t.icons_by_filetype.file, } } } diff --git a/src/theme.rs b/src/theme.rs index 704e3ed..c284193 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -11,7 +11,7 @@ use crate::print_error; use color::ColorTheme; use icon::IconTheme; -#[derive(Debug, Deserialize, PartialEq)] +#[derive(Debug, Deserialize, Default, PartialEq)] #[serde(rename_all = "kebab-case")] #[serde(deny_unknown_fields)] #[serde(default)] @@ -20,16 +20,6 @@ pub struct Theme { pub icon: IconTheme, } -impl Default for Theme { - fn default() -> Self { - // TODO(zwpaper): check terminal color and return light or dark - Theme { - color: ColorTheme::default(), - icon: IconTheme::default(), - } - } -} - impl Theme { /// This read theme from file, /// use the file path if it is absolute diff --git a/src/theme/icon.rs b/src/theme/icon.rs index a11b8a3..811f25f 100644 --- a/src/theme/icon.rs +++ b/src/theme/icon.rs @@ -8,31 +8,76 @@ use std::collections::HashMap; pub struct IconTheme { pub icons_by_name: HashMap, pub icons_by_extension: HashMap, - // pub icons_by_filetype: HashMap, - pub default_folder_icon: String, - pub default_file_icon: String, + pub icons_by_filetype: IconByType, +} + +#[derive(Debug, Deserialize, PartialEq)] +#[serde(rename_all = "kebab-case")] +#[serde(deny_unknown_fields)] +#[serde(default)] +pub struct IconByType { + pub dir: String, + pub file: String, + pub pipe: String, + pub socket: String, + pub executable: String, + pub device_char: String, + pub device_block: String, + pub special: String, + pub symlink_dir: String, + pub symlink_file: String, } impl Default for IconTheme { fn default() -> Self { - // TODO(zwpaper): check terminal color and return light or dark IconTheme { icons_by_name: Self::get_default_icons_by_name(), icons_by_extension: Self::get_default_icons_by_extension(), - default_folder_icon: "\u{f115}".into(), - default_file_icon: "\u{f016}".into(), + icons_by_filetype: IconByType::default(), + } + } +} + +impl Default for IconByType { + fn default() -> IconByType { + IconByType { + dir: "\u{f115}".into(), //  + file: "\u{f016}".into(), //  + pipe: "\u{f731}".into(), //  + socket: "\u{f6a7}".into(), //  + executable: "\u{f489}".into(), //  + symlink_dir: "\u{f482}".into(), //  + symlink_file: "\u{f481}".into(), //  + device_char: "\u{e601}".into(), //  + device_block: "\u{fc29}".into(), // ﰩ + special: "\u{f2dc}".into(), //  + } + } +} + +impl IconByType { + pub fn unicode() -> Self { + IconByType { + dir: "\u{1f4c2}".into(), + file: "\u{1f4c4}".into(), + pipe: "\u{1f4e9}".into(), + socket: "\u{1f4ec}".into(), + executable: "\u{1f3d7}".into(), + symlink_dir: "\u{1f5c2}".into(), + symlink_file: "\u{1f516}".into(), + device_char: "\u{1f5a8}".into(), + device_block: "\u{1f4bd}".into(), + special: "\u{1f4df}".into(), } } } impl IconTheme { pub fn unicode() -> Self { - // TODO(zwpaper): check terminal color and return light or dark IconTheme { icons_by_name: HashMap::new(), icons_by_extension: HashMap::new(), - default_folder_icon: "\u{1f5cb}".into(), - default_file_icon: "\u{1f5c1}".into(), + icons_by_filetype: IconByType::unicode(), } }