use std::collections::HashMap;
use std::fmt;
use lazy_static::lazy_static;
use serde::de::{self, Deserialize, Deserializer, MapAccess, Visitor};
use serde_derive::Deserialize;
use crate::util;
lazy_static! {
pub static ref NONE: HashMap<String, String> = map_to_owned! {
"" => "",
"backlight_empty" => "BRIGHT",
"backlight_full" => "BRIGHT",
"backlight_1" => "BRIGHT",
"backlight_2" => "BRIGHT",
"backlight_3" => "BRIGHT",
"backlight_4" => "BRIGHT",
"backlight_5" => "BRIGHT",
"backlight_6" => "BRIGHT",
"backlight_7" => "BRIGHT",
"backlight_8" => "BRIGHT",
"backlight_9" => "BRIGHT",
"backlight_10" => "BRIGHT",
"backlight_11" => "BRIGHT",
"backlight_12" => "BRIGHT",
"backlight_13" => "BRIGHT",
"bat" => "BAT",
"bat_charging" => "CHG",
"bat_discharging" => "DCG",
"bat_empty" => "EMP",
"bat_full" => "FULL",
"bat_half" => "BAT",
"bat_not_available" => "BAT N/A",
"bat_quarter" => "BAT",
"bat_three_quarters" => "BAT",
"bell" => "ON",
"bell-slash" => "OFF",
"bluetooth" => "BT",
"calendar" => "CAL",
"cogs" => "LOAD",
"cpu" => "CPU",
"disk_drive" => "DISK",
"docker" => "DOCKER",
"github" => "GITHUB",
"gpu" => "GPU",
"headphones" => "HEAD",
"joystick" => "JOY",
"keyboard" => "KBD",
"mail" => "MAIL",
"memory_mem" => "MEM",
"memory_swap" => "SWAP",
"mouse" => "MOUSE",
"music" => "MUSIC",
"music_next" => ">",
"music_pause" => "||",
"music_play" => ">",
"music_prev" => "<",
"net_down" => "DOWN",
"net_loopback" => "LO",
"net_up" => "UP ",
"net_vpn" => "VPN",
"net_wired" => "ETH",
"net_wireless" => "WLAN",
"notification" => "NOTIF",
"phone" => "PHONE",
"phone_disconnected" => "PHONE",
"ping" => "PING",
"pomodoro" => "POMODORO",
"resolution" => "RES",
"tasks" => "TSK",
"thermometer" => "TEMP",
"time" => "TIME",
"toggle_off" => "OFF",
"toggle_on" => "ON",
"update" => "UPD",
"uptime" => "UP",
"volume_empty" => "VOL",
"volume_full" => "VOL",
"volume_half" => "VOL",
"volume_muted" => "VOL MUTED",
"microphone_empty" => "MIC ",
"microphone_full" => "MIC",
"microphone_half" => "MIC",
"microphone_muted" => "MIC MUTED",
"weather_clouds" => "CLOUDY",
"weather_default" => "WEATHER",
"weather_rain" => "RAIN",
"weather_snow" => "SNOW",
"weather_sun" => "SUNNY",
"weather_thunder" => "STORM",
"xrandr" => "SCREEN"
};
pub static ref AWESOME: HashMap<String, String> = map_to_owned! {
"" => "",
"backlight_empty" => "\u{1f315}",
"backlight_full" => "\u{1f311}",
"backlight_1" => "\u{1f314}",
"backlight_2" => "\u{1f314}",
"backlight_3" => "\u{1f314}",
"backlight_4" => "\u{1f314}",
"backlight_5" => "\u{1f313}",
"backlight_6" => "\u{1f313}",
"backlight_7" => "\u{1f313}",
"backlight_8" => "\u{1f313}",
"backlight_9" => "\u{1f313}",
"backlight_10" => "\u{1f312}",
"backlight_11" => "\u{1f312}",
"backlight_12" => "\u{1f312}",
"backlight_13" => "\u{1f312}",
"bat_charging" => "\u{f1e6}",
"bat_discharging" => "\u{f242}",
"bat_empty" => "\u{f244}",
"bat_full" => "\u{f240}",
"bat_half" => "\u{f242}",
"bat_not_available" => "\u{f244}",
"bat_quarter" => "\u{f243}",
"bat_three_quarters" => "\u{f241}",
"bell" => "\u{f0f3}",
"bell-slash" => "\u{f1f7}",
"bluetooth" => "\u{f294}",
"calendar" => "\u{f073}",
"cogs" => "\u{f085}",
"cpu" => "\u{f0e4}",
"disk_drive" => "\u{f0a0}",
"docker" => "\u{f21a}",
"github" => "\u{f09b}",
"gpu" => "\u{f26c}",
"headphones" => "\u{f025}",
"joystick" => "\u{f11b}",
"keyboard" => "\u{f11c}",
"mail" => "\u{f0e0}",
"memory_mem" => "\u{f2db}",
"memory_swap" => "\u{f0a0}",
"mouse" => "\u{f245}",
"music" => "\u{f001}",
"music_next" => "\u{f061}",
"music_pause" => "\u{f04c}",
"music_play" => "\u{f04b}",
"music_prev" => "\u{f060}",
"net_bridge" => "\u{f0e8}",
"net_down" => "\u{2b07}",
"net_loopback" => "LO",
"net_modem" => "\u{f095}",
"net_up" => "\u{2b06}",
"net_vpn" => "\u{f023}",
"net_wired" => "\u{f0ac}",
"net_wireless" => "\u{f1eb}",
"notification" => "\u{f0a2}",
"phone" => "\u{f10b}",
"phone_disconnected" => "\u{1f4f5}",
"ping" => "\u{21ba}",
"pomodoro" => "\u{1f345}",
"resolution" => "\u{f096}",
"tasks" => "\u{f0ae}",
"thermometer" => "\u{f2c8}",
"time" => "\u{f017}",
"toggle_off" => "\u{f204}",
"toggle_on" => "\u{f205}",
"unknown" => "\u{f128}",
"update" => "\u{f062}",
"uptime" => "\u{f017}",
"volume_empty" => "\u{f026}",
"volume_full" => "\u{f028}",
"volume_half" => "\u{f027}",
"volume_muted" => "\u{f026} \u{f00d}",
"microphone_empty" => "\u{f130}",
"microphone_full" => "\u{f130}",
"microphone_half" => "\u{f130}",
"microphone_muted" => "\u{f131}",
"weather_clouds" => "\u{f0c2}",
"weather_default" => "\u{f0c2}",
"weather_rain" => "\u{f043}",
"weather_snow" => "\u{f2dc}",
"weather_sun" => "\u{f185}",
"weather_thunder" => "\u{f0e7}",
"xrandr" => "\u{f26c}"
};
pub static ref AWESOME5: HashMap<String, String> = map_to_owned! {
"" => "",
"backlight_empty" => "\u{1f315}",
"backlight_full" => "\u{1f311}",
"backlight_1" => "\u{1f314}",
"backlight_2" => "\u{1f314}",
"backlight_3" => "\u{1f314}",
"backlight_4" => "\u{1f314}",
"backlight_5" => "\u{1f313}",
"backlight_6" => "\u{1f313}",
"backlight_7" => "\u{1f313}",
"backlight_8" => "\u{1f313}",
"backlight_9" => "\u{1f313}",
"backlight_10" => "\u{1f312}",
"backlight_11" => "\u{1f312}",
"backlight_12" => "\u{1f312}",
"backlight_13" => "\u{1f312}",
"bat_charging" => "\u{f1e6}",
"bat_discharging" => "\u{f242}",
"bat_empty" => "\u{f244}",
"bat_full" => "\u{f240}",
"bat_half" => "\u{f242}",
"bat_quarter" => "\u{f243}",
"bat_three_quarters" => "\u{f241}",
"bell" => "\u{f0f3}",
"bell-slash" => "\u{f1f6}",
"bluetooth" => "\u{f294}",
"calendar" => "\u{f073}",
"cogs" => "\u{f085}",
"cpu" => "\u{f3fd}",
"disk_drive" => "\u{f8b5}",
"docker" => "\u{f21a}",
"github" => "\u{f09b}",
"gpu" => "\u{f26c}",
"headphones" => "\u{f025}",
"joystick" => "\u{f11b}",
"keyboard" => "\u{f11c}",
"mail" => "\u{f0e0}",
"memory_mem" => "\u{f2db}",
"memory_swap" => "\u{f0a0}",
"mouse" => "\u{f245}",
"music" => "\u{f001}",
"music_next" => "\u{f061}",
"music_pause" => "\u{f04c}",
"music_play" => "\u{f04b}",
"music_prev" => "\u{f060}",
"net_bridge" => "\u{f0e8}",
"net_down" => "\u{f019}",
"net_loopback" => "LO ",
"net_modem" => "\u{f095}",
"net_up" => "\u{f093}",
"net_vpn" => "\u{f023}",
"net_wired" => "\u{f6ff}",
"net_wireless" => "\u{f1eb}",
"notification" => "\u{f0f3}",
"phone" => "\u{f3cd}",
"phone_disconnected" => "\u{1f4f5}",
"ping" => "\u{f362}",
"pomodoro" => "\u{1f345}",
"resolution" => "\u{f096}",
"tasks" => "\u{f0ae}",
"thermometer" => "\u{f2c8}",
"time" => "\u{f017}",
"toggle_off" => "\u{f204}",
"toggle_on" => "\u{f205}",
"unknown" => "\u{f128}",
"update" => "\u{f062}",
"uptime" => "\u{f2f2}",
"volume_empty" => "\u{f026}",
"volume_full" => "\u{f028}",
"volume_half" => "\u{f027}",
"volume_muted" => "\u{f6a9}",
"microphone_full" => "\u{f3c9}",
"microphone_half" => "\u{f3c9}",
"microphone_empty" => "\u{f3c9}",
"microphone_muted" => "\u{f539}",
"weather_clouds" => "\u{f0c2}",
"weather_default" => "\u{f0c2}",
"weather_rain" => "\u{f043}",
"weather_snow" => "\u{f2dc}",
"weather_sun" => "\u{f185}",
"weather_thunder" => "\u{f0e7}",
"xrandr" => "\u{f26c}"
};
pub static ref MATERIAL: HashMap<String, String> = map_to_owned! {
"" => "",
"bat_charging" => "\u{e1a3}",
"bat_discharging" => "\u{e19c}",
"bat_empty" => "\u{e19c}",
"bat_full" => "\u{e1a4}",
"bat_half" => "\u{e1a5}",
"bat_quarter" => "\u{e1a5}",
"bat_three_quarters" => "\u{e1a5}",
"bat_not_available" => "\u{e1a6}",
"bell" => "\u{e7f4}",
"bell-slash" => "\u{e7f8}",
"bluetooth" => "\u{e1a7}",
"calendar" => "\u{e935}",
"cogs" => "\u{e8b8}",
"cpu" => "\u{e640}",
"disk_drive" => "\u{e1db}",
"docker" => "\u{e532}",
"github" => "\u{e86f}",
"gpu" => "\u{e333}",
"headphones" => "\u{e60f}",
"joystick" => "\u{e30f}",
"keyboard" => "\u{e312}",
"mail" => "\u{e0be}",
"memory_mem" => "\u{e322}",
"memory_swap" => "\u{e8d4}",
"mouse" => "\u{e323}",
"music" => "\u{e405}",
"music_next" => "\u{e044}",
"music_pause" => "\u{e034}",
"music_play" => "\u{e037}",
"music_prev" => "\u{e045}",
"net_loopback" => "LO",
"notification" => "\u{e7f7}",
"phone" => "\u{e324}",
"phone_disconnected" => "\u{e339}",
"ping" => "\u{e62a}",
"pomodoro" => "\u{1f345}",
"resolution" => "\u{f152}",
"tasks" => "\u{e8f9}",
"thermometer" => "\u{e1ff}",
"time" => "\u{e192}",
"toggle_off" => "\u{e836}",
"toggle_on" => "\u{e837}",
"update" => "\u{e8d7}",
"uptime" => "\u{e425}",
"volume_empty" => "\u{e04e}",
"volume_full" => "\u{e050}",
"volume_half" => "\u{e04d}",
"volume_muted" => "\u{e04f}",
"microphone_full" => "\u{e029}",
"microphone_half" => "\u{e029}",
"microphone_empty" => "\u{e02a}",
"microphone_muted" => "\u{e02b}",
"weather_clouds" => "\u{e42d}",
"weather_default" => "\u{e42d}",
"weather_sun" => "\u{e430}",
"xrandr" => "\u{e31e}"
};
pub static ref MATERIAL_NF: HashMap<String, String> = map_to_owned! {
"" => "",
"backlight_empty" => "\u{e38d}",
"backlight_full" => "\u{e39b}",
"backlight_1" => "\u{e3d4}",
"backlight_2" => "\u{e3d3}",
"backlight_3" => "\u{e3d2}",
"backlight_4" => "\u{e3d1}",
"backlight_5" => "\u{e3d0}",
"backlight_6" => "\u{e3cf}",
"backlight_7" => "\u{e3ce}",
"backlight_8" => "\u{e3cd}",
"backlight_9" => "\u{e3cc}",
"backlight_10" => "\u{e3cb}",
"backlight_11" => "\u{e3ca}",
"backlight_12" => "\u{e3c9}",
"backlight_13" => "\u{e3c8}",
"bat_charging" => "\u{f583}",
"bat_discharging" => "\u{f57d}",
"bat_empty" => "\u{f58d}",
"bat_full" => "\u{f578}",
"bat_half" => "\u{f57d}",
"bat_quarter" => "\u{f57a}",
"bat_three_quarters" => "\u{f57f}",
"bell" => "\u{f599}",
"bell-slash" => "\u{f59a}",
"bluetooth" => "\u{f5ae}",
"calendar" => "\u{f5ec}",
"cogs" => "\u{f992}",
"cpu" => "\u{f9c4}",
"disk_drive" => "\u{f7c9}",
"docker" => "\u{f308}",
"github" => "\u{f7a3}",
"gpu" => "\u{f878}",
"headphones" => "\u{f7ca}",
"joystick" => "\u{f796}",
"keyboard" => "\u{f80b}",
"mail" => "\u{f6ed}",
"memory_mem" => "\u{f85a}",
"memory_swap" => "\u{f7c9}",
"mouse" => "\u{f87c}",
"music" => "\u{f886}",
"music_next" => "\u{f9ac}",
"music_pause" => "\u{f8e3}",
"music_play" => "\u{f909}",
"music_prev" => "\u{f9ad}",
"net_bridge" => "\u{f9a9}",
"net_down" => "\u{f6d9}",
"net_loopback" => "\u{fbe9}",
"net_modem" => "\u{f8f1}",
"net_up" => "\u{fa51}",
"net_vpn" => "\u{fa81}",
"net_wired" => "\u{f6ff}",
"net_wireless" => "\u{faa8}",
"notification" => "\u{f599}",
"phone" => "\u{f8f1}",
"phone_disconnected" => "\u{fb57}",
"ping" => "\u{fa1e}",
"pomodoro" => "\u{e001}",
"resolution" => "\u{f792}",
"tasks" => "\u{fac6}",
"thermometer" => "\u{fa0e}",
"time" => "\u{f64f}",
"toggle_off" => "\u{fa21}",
"toggle_on" => "\u{fa20}",
"unknown" => "\u{f685}",
"update" => "\u{fbae}",
"uptime" => "\u{f652}",
"volume_empty" => "\u{fa7e}",
"volume_full" => "\u{fa7d}",
"volume_half" => "\u{fa7f}",
"volume_muted" => "\u{f466}",
"microphone_full" => "\u{f86b}",
"microphone_half" => "\u{f86b}",
"microphone_empty" => "\u{f86d}",
"microphone_muted" => "\u{f86c}",
"weather_clouds" => "\u{fa8f}",
"weather_default" => "\u{fa8f}",
"weather_rain" => "\u{fa95}",
"weather_snow" => "\u{fa97}",
"weather_sun" => "\u{fa98}",
"weather_thunder" => "\u{e31d}",
"xrandr" => "\u{f879}"
};
}
#[derive(Debug, Clone)]
pub struct Icons(pub HashMap<String, String>);
impl Default for Icons {
fn default() -> Self {
Self(NONE.clone())
}
}
impl Icons {
pub fn from_name(name: &str) -> Option<Self> {
match name {
"material" => Some(Icons(MATERIAL.clone())),
"material-nf" => Some(Icons(MATERIAL_NF.clone())),
"awesome" => Some(Icons(AWESOME.clone())),
"awesome5" => Some(Icons(AWESOME5.clone())),
"none" => Some(Icons(NONE.clone())),
_ => None,
}
}
pub fn from_file(file: &str) -> Option<Self> {
let file = util::find_file(file, Some("icons"), Some(".toml"))?;
let icons: HashMap<String, String> = util::deserialize_file(&file).ok()?;
Some(Icons(icons))
}
}
impl<'de> Deserialize<'de> for Icons {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Name,
File,
Overrides,
}
struct IconsVisitor;
impl<'de> Visitor<'de> for IconsVisitor {
type Value = Icons;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Icons")
}
fn visit_str<E>(self, name: &str) -> Result<Icons, E>
where
E: de::Error,
{
Icons::from_name(name)
.ok_or_else(|| de::Error::custom(format!("Icon set \"{}\" not found.", name)))
}
fn visit_map<V>(self, mut map: V) -> Result<Icons, V::Error>
where
V: MapAccess<'de>,
{
let mut icons = None;
let mut overrides: Option<HashMap<String, String>> = None;
while let Some(key) = map.next_key()? {
match key {
Field::Name => {
if icons.is_some() {
return Err(de::Error::duplicate_field("name or file"));
}
let name = map.next_value()?;
icons = Some(Icons::from_name(name).ok_or_else(|| {
de::Error::custom(format!("Icon set \"{}\" not found.", name))
})?);
}
Field::File => {
if icons.is_some() {
return Err(de::Error::duplicate_field("name or file"));
}
let file = map.next_value()?;
icons = Some(Icons::from_file(file).ok_or_else(|| {
de::Error::custom(format!(
"Failed to load icon set from file {}.",
file
))
})?);
}
Field::Overrides => {
if overrides.is_some() {
return Err(de::Error::duplicate_field("overrides"));
}
overrides = Some(map.next_value()?);
}
}
}
let mut icons = icons.unwrap_or_default();
if let Some(overrides) = overrides {
for icon in overrides {
icons.0.insert(icon.0, icon.1);
}
}
Ok(icons)
}
}
deserializer.deserialize_any(IconsVisitor)
}
}