use serde::Deserialize;
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).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)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct IconTheme {
#[serde(deserialize_with = "deserialize_by_name")]
pub name: HashMap<String, String>,
#[serde(deserialize_with = "deserialize_by_extension")]
pub extension: HashMap<String, String>,
pub filetype: ByType,
}
#[derive(Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
#[serde(deny_unknown_fields)]
#[serde(default)]
pub struct ByType {
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 {
IconTheme {
name: Self::get_default_icons_by_name(),
extension: Self::get_default_icons_by_extension(),
filetype: ByType::default(),
}
}
}
impl Default for ByType {
fn default() -> ByType {
ByType {
dir: "\u{f115}".into(), //
file: "\u{f016}".into(), //
pipe: "\u{f0232}".into(), //
socket: "\u{f01a8}".into(), //
executable: "\u{f489}".into(), //
symlink_dir: "\u{f482}".into(), //
symlink_file: "\u{f481}".into(), //
device_char: "\u{e601}".into(), //
device_block: "\u{f072b}".into(), //
special: "\u{f2dc}".into(), //
}
}
}
impl ByType {
pub fn unicode() -> Self {
ByType {
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 {
IconTheme {
name: HashMap::new(),
extension: HashMap::new(),
filetype: ByType::unicode(),
}
}
// pub only for testing in icons.rs
pub fn get_default_icons_by_name() -> HashMap<String, String> {
// Note: filenames must be lower-case
[
("a.out", "\u{f489}"), // ""
("api", "\u{f048d}"), // ""
(".asoundrc", "\u{e615}"), // ""
(".atom", "\u{e764}"), // ""
(".ash", "\u{f489}"), // ""
(".ash_history", "\u{f489}"), // ""
("authorized_keys", "\u{e60a}"), // ""
("assets", "\u{f0c7}"), // ""
(".android", "\u{f17b}"), // ""
(".audacity-data", "\u{e5fc}"), // ""
("backups", "\u{f006f}"), // ""
(".bash_history", "\u{f1183}"), // ""
(".bash_logout", "\u{f1183}"), // ""
(".bash_profile", "\u{f1183}"), // ""
(".bashrc", "\u{f1183}"), // ""
("bin", "\u{e5fc}"), // ""
(".bpython_history", "\u{e606}"), // ""
("build", "\u{f487}"), // ""
("bspwmrc", "\u{e615}"), // ""
("build.ninja", "\u{f0ad}"), // ""
(".cache", "\u{f00e8}"), // ""
("cache", "\u{f00e8}"), // ""
("cargo.lock", "\u{e68b}"), // ""
("cargo.toml", "\u{e68b}"), // ""
(".cargo", "\u{e68b}"), // ""
(".ccls-cache",