use std::{ fmt::{Display, Write}, str::FromStr, }; use serde::{Deserialize, Serialize}; use strum::IntoEnumIterator; use super::StringParseError; pub struct TagStatus { name: String, state: TagState, } #[allow(unused)] impl TagStatus { pub fn name(&self) -> &str { &self.name } pub fn state(&self) -> TagState { self.state } } impl FromStr for TagStatus { type Err = StringParseError; fn from_str(s: &str) -> Result { let mut parts = s.chars(); let state = parts .next() .ok_or(StringParseError::UnknownValue)? .try_into()?; let name = parts.collect(); Ok(Self { name, state }) } } #[derive(Debug, Clone, Copy, Serialize, Deserialize, strum::EnumIter)] pub enum TagState { Empty, NotEmpty, /// The tag contains an urgent window Urgent, /// The tag is viewed on the specified MONITOR and it is focused SameMonitorFocused, /// The tag is viewed on the specified MONITOR, but this monitor is not focused SameMonitor, /// The tag is viewed on a different MONITOR and it is focused DifferentMonitorFocused, /// The tag is viewed on a different MONITOR, but this monitor is not focused DifferentMonitor, } impl TryFrom for TagState { type Error = StringParseError; fn try_from(value: char) -> Result { Self::iter() .into_iter() .find(|i| char::from(i) == value) .ok_or(StringParseError::UnknownValue) } } impl FromStr for TagState { type Err = StringParseError; fn from_str(s: &str) -> Result { Self::iter() .into_iter() .find(|i| i.to_string() == s) .ok_or(StringParseError::UnknownValue) } } impl From<&TagState> for char { fn from(value: &TagState) -> Self { match value { TagState::SameMonitorFocused => '#', TagState::SameMonitor => '+', TagState::DifferentMonitorFocused => '%', TagState::DifferentMonitor => '-', TagState::Empty => '.', TagState::NotEmpty => ':', TagState::Urgent => '!', } } } impl Display for TagState { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.write_char(self.into()) } }