use std::fmt;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Selector {
pub style: Option<String>,
states: Vec<String>,
dirty: bool,
}
impl Selector {
pub fn new(style: impl Into<String>) -> Self {
Selector {
style: Some(style.into()),
states: vec![],
dirty: true,
}
}
pub fn states(&self) -> &Vec<String> {
&self.states
}
pub fn push_state(&mut self, state: impl Into<String>) {
let state = state.into();
if self.states.contains(&state) {
return;
}
self.states.push(state);
self.dirty = true;
}
pub fn remove_all_similar_states(&mut self, pattern: &str) {
while let Some(pos) = self.states.iter().position(|x| x.contains(pattern)) {
self.states.remove(pos);
self.dirty = true;
}
}
pub fn remove_state(&mut self, state: impl Into<String>) -> Option<String> {
let state: String = state.into();
if !state.is_empty() && self.states.contains(&state) {
while let Some(pos) = self.states.iter().position(|x| *x == state) {
self.states.remove(pos);
}
self.dirty = true;
return Some(state);
}
None
}
pub fn pop_state(&mut self) -> Option<String> {
self.dirty = true;
self.states.pop()
}
pub fn dirty(&self) -> bool {
self.dirty
}
pub fn set_dirty(&mut self, dirty: bool) {
self.dirty = dirty;
}
pub fn has_state(&self, state: &str) -> bool {
self.states.contains(&state.to_string())
}
}
impl fmt::Display for Selector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(style) = &self.style {
return write!(f, "Selector ( style: {} )", style);
}
write!(f, "Selector ( empty )")
}
}
impl From<&str> for Selector {
fn from(s: &str) -> Self {
Selector::new(s)
}
}
impl From<String> for Selector {
fn from(s: String) -> Self {
Selector::new(s)
}
}