🔨 icon: refactor to use icon by file type

This commit is contained in:
Wei Zhang 2022-07-31 17:06:30 +08:00 committed by Abin Simon
parent 6df27aebad
commit a60ab3d3e4
5 changed files with 74 additions and 42 deletions

View file

@ -1,10 +1,7 @@
use crate::color::Colors; use crate::color::Colors;
use crate::display; use crate::display;
use crate::flags::{ use crate::flags::{ColorOption, Display, Flags, HyperlinkOption, Layout, SortOrder, ThemeOption};
ColorOption, Display, Flags, HyperlinkOption, IconOption, IconTheme, Layout, SortOrder, use crate::icon::Icons;
ThemeOption,
};
use crate::icon::{self, Icons};
use crate::meta::Meta; use crate::meta::Meta;
use crate::{print_error, print_output, sort, ExitCode}; use crate::{print_error, print_output, sort, ExitCode};
use std::path::PathBuf; use std::path::PathBuf;

View file

@ -90,7 +90,7 @@ impl Configurable<Self> for IconOption {
} }
/// The flag showing which icon theme to use. /// 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")] #[serde(rename_all = "kebab-case")]
pub enum IconTheme { pub enum IconTheme {
Unicode, Unicode,

View file

@ -36,34 +36,34 @@ impl Icons {
// Check file types // Check file types
let file_type: FileType = name.file_type(); let file_type: FileType = name.file_type();
let icon = match file_type { let icon = match file_type {
FileType::SymLink { is_dir: true } => "\u{f482}", // "" FileType::SymLink { is_dir: true } => &t.icons_by_filetype.symlink_dir,
FileType::SymLink { is_dir: false } => "\u{f481}", // "" FileType::SymLink { is_dir: false } => &t.icons_by_filetype.symlink_file,
FileType::Socket => "\u{f6a7}", // "" FileType::Socket => &t.icons_by_filetype.socket,
FileType::Pipe => "\u{f731}", // "" FileType::Pipe => &t.icons_by_filetype.pipe,
FileType::CharDevice => "\u{e601}", // "" FileType::CharDevice => &t.icons_by_filetype.device_char,
FileType::BlockDevice => "\u{fc29}", // "ﰩ" FileType::BlockDevice => &t.icons_by_filetype.device_block,
FileType::Special => "\u{f2dc}", // "" FileType::Special => &t.icons_by_filetype.special,
_ => { _ => {
// Use the known names
if let Some(icon) = t if let Some(icon) = t
.icons_by_name .icons_by_name
.get(name.file_name().to_lowercase().as_str()) .get(name.file_name().to_lowercase().as_str())
{ {
icon icon
} } else if let Some(icon) = name
// Use the known extensions .extension()
else if let Some(icon) = name.extension().and_then(|extension| { .and_then(|ext| t.icons_by_extension.get(ext.to_lowercase().as_str()))
t.icons_by_extension.get(extension.to_lowercase().as_str()) {
}) {
icon icon
} else { } else {
match file_type { 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. // If a file has no extension and is executable, show an icon.
// Except for Windows, it marks everything as an executable. // Except for Windows, it marks everything as an executable.
#[cfg(not(windows))] #[cfg(not(windows))]
FileType::File { exec: true, .. } => "\u{f489}", // "" FileType::File { exec: true, .. } => {
_ => &t.default_file_icon, &t.icons_by_filetype.executable
}
_ => &t.icons_by_filetype.file,
} }
} }
} }

View file

@ -11,7 +11,7 @@ use crate::print_error;
use color::ColorTheme; use color::ColorTheme;
use icon::IconTheme; use icon::IconTheme;
#[derive(Debug, Deserialize, PartialEq)] #[derive(Debug, Deserialize, Default, PartialEq)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
#[serde(default)] #[serde(default)]
@ -20,16 +20,6 @@ pub struct Theme {
pub icon: IconTheme, 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 { impl Theme {
/// This read theme from file, /// This read theme from file,
/// use the file path if it is absolute /// use the file path if it is absolute

View file

@ -8,31 +8,76 @@ use std::collections::HashMap;
pub struct IconTheme { pub struct IconTheme {
pub icons_by_name: HashMap<String, String>, pub icons_by_name: HashMap<String, String>,
pub icons_by_extension: HashMap<String, String>, pub icons_by_extension: HashMap<String, String>,
// pub icons_by_filetype: HashMap<String, String>, pub icons_by_filetype: IconByType,
pub default_folder_icon: String, }
pub default_file_icon: String,
#[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 { impl Default for IconTheme {
fn default() -> Self { fn default() -> Self {
// TODO(zwpaper): check terminal color and return light or dark
IconTheme { IconTheme {
icons_by_name: Self::get_default_icons_by_name(), icons_by_name: Self::get_default_icons_by_name(),
icons_by_extension: Self::get_default_icons_by_extension(), icons_by_extension: Self::get_default_icons_by_extension(),
default_folder_icon: "\u{f115}".into(), icons_by_filetype: IconByType::default(),
default_file_icon: "\u{f016}".into(), }
}
}
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 { impl IconTheme {
pub fn unicode() -> Self { pub fn unicode() -> Self {
// TODO(zwpaper): check terminal color and return light or dark
IconTheme { IconTheme {
icons_by_name: HashMap::new(), icons_by_name: HashMap::new(),
icons_by_extension: HashMap::new(), icons_by_extension: HashMap::new(),
default_folder_icon: "\u{1f5cb}".into(), icons_by_filetype: IconByType::unicode(),
default_file_icon: "\u{1f5c1}".into(),
} }
} }