Icon theme with overrides from config (#792)

This commit is contained in:
Mikihiro SUDA 2023-04-22 23:14:49 +09:00 committed by GitHub
parent 5ecb868c19
commit ff3e48e20b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 0 deletions

View file

@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[`LS_COLORS`](README.md#Colors) can be used to customize. [`LS_COLORS`](README.md#Colors) can be used to customize.
- Handle dereference (-L) with broken symlink from [r3dArch](https://github.com/r3dArch) - Handle dereference (-L) with broken symlink from [r3dArch](https://github.com/r3dArch)
- Avoid using Clap's deprecated structs and functions [sudame](https://github.com/sudame) - Avoid using Clap's deprecated structs and functions [sudame](https://github.com/sudame)
- Icon theme with overrides from config [sudame](https://github.com/sudame)
## [0.23.1] - 2022-09-13 ## [0.23.1] - 2022-09-13

View file

@ -1,12 +1,48 @@
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
enum ByFilename {
Name,
Extension,
}
fn deserialize_by_filename<'de, D>(
deserializer: D,
by: ByFilename,
) -> Result<HashMap<String, String>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
let default = match by {
ByFilename::Name => IconTheme::get_default_icons_by_name(),
ByFilename::Extension => IconTheme::get_default_icons_by_extension(),
};
HashMap::<_, _>::deserialize(deserializer)
.map(|input| default.into_iter().chain(input.into_iter()).collect())
}
fn deserialize_by_name<'de, D>(deserializer: D) -> Result<HashMap<String, String>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
deserialize_by_filename(deserializer, ByFilename::Name)
}
fn deserialize_by_extension<'de, D>(deserializer: D) -> Result<HashMap<String, String>, D::Error>
where
D: serde::de::Deserializer<'de>,
{
deserialize_by_filename(deserializer, ByFilename::Extension)
}
#[derive(Debug, Deserialize, PartialEq, Eq)] #[derive(Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)] #[serde(deny_unknown_fields)]
#[serde(default)] #[serde(default)]
pub struct IconTheme { pub struct IconTheme {
#[serde(deserialize_with = "deserialize_by_name")]
pub name: HashMap<String, String>, pub name: HashMap<String, String>,
#[serde(deserialize_with = "deserialize_by_extension")]
pub extension: HashMap<String, String>, pub extension: HashMap<String, String>,
pub filetype: ByType, pub filetype: ByType,
} }
@ -656,4 +692,36 @@ filetype:
let empty: IconTheme = Theme::with_yaml("filetype:\n dir: ").unwrap(); let empty: IconTheme = Theme::with_yaml("filetype:\n dir: ").unwrap();
assert_eq!(empty.filetype.dir, ""); assert_eq!(empty.filetype.dir, "");
} }
#[test]
fn test_custom_icon_by_name() {
// When a user sets to use 📦-icon for a cargo.toml file,
let theme: IconTheme = Theme::with_yaml("name:\n cargo.toml: 📦").unwrap();
// 📦-icon should be used for a cargo.toml file.
assert_eq!(theme.name.get("cargo.toml").unwrap(), "📦");
}
#[test]
fn test_default_icon_by_name_with_custom_entry() {
// When a user sets to use 📦-icon for a cargo.toml file,
let theme: IconTheme = Theme::with_yaml("name:\n cargo.toml: 📦").unwrap();
// the default icon  should be used for a cargo.lock file.
assert_eq!(theme.name.get("cargo.lock").unwrap(), "\u{e7a8}");
}
#[test]
fn test_custom_icon_by_extension() {
// When a user sets to use 🦀-icon for *.rs files,
let theme: IconTheme = Theme::with_yaml("extension:\n rs: 🦀").unwrap();
// 🦀-icon should be used for *.rs files.
assert_eq!(theme.extension.get("rs").unwrap(), "🦀");
}
#[test]
fn test_default_icon_by_extension_with_custom_entry() {
// When a user sets to use 🦀-icon for *.rs files,
let theme: IconTheme = Theme::with_yaml("extension:\n rs: 🦀").unwrap();
// the default icon  should be used for *.go files.
assert_eq!(theme.extension.get("go").unwrap(), "\u{e627}");
}
} }