use std::collections::BTreeMap;
use std::sync::Arc;
use super::paint::{Expr, Paint};
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum PropValue {
Paint(Paint),
Flag(bool),
Cells(u16),
Pair(u16, u16),
Word(&'static str),
}
pub const WORD_PROPS: [(&str, &str, &[&str]); 1] = [("scrollbar", "style", &["block", "half", "thin", "dots"])];
pub(crate) fn allowed_words(widget: &str, key: &str) -> Option<&'static [&'static str]> {
WORD_PROPS.iter().find(|(w, k, _)| *w == widget && *k == key).map(|(_, _, words)| *words)
}
#[derive(Debug, Clone, Default, PartialEq)]
pub struct StyleProps {
values: Arc<BTreeMap<String, PropValue>>,
}
impl StyleProps {
#[must_use]
pub fn get(&self, key: &str) -> Option<PropValue> {
self.values.get(key).copied()
}
#[must_use]
pub fn paint(&self, key: &str) -> Option<Paint> {
match self.get(key)? {
PropValue::Paint(paint) => Some(paint),
_ => None,
}
}
#[must_use]
pub fn flag(&self, key: &str) -> bool {
matches!(self.get(key), Some(PropValue::Flag(true)))
}
#[must_use]
pub fn cells(&self, key: &str) -> Option<u16> {
match self.get(key)? {
PropValue::Cells(n) => Some(n),
_ => None,
}
}
#[must_use]
pub fn pair(&self, key: &str) -> Option<(u16, u16)> {
match self.get(key)? {
PropValue::Pair(v, h) => Some((v, h)),
_ => None,
}
}
#[must_use]
pub fn word(&self, key: &str) -> Option<&'static str> {
match self.get(key)? {
PropValue::Word(word) => Some(word),
_ => None,
}
}
#[must_use]
pub fn is_animated(&self) -> bool {
self.values.values().any(|value| matches!(value, PropValue::Paint(paint) if paint.is_animated()))
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.values.is_empty()
}
pub fn iter(&self) -> impl Iterator<Item = (&str, PropValue)> {
self.values.iter().map(|(key, value)| (key.as_str(), *value))
}
pub(crate) fn set(&mut self, key: &str, value: PropValue) {
Arc::make_mut(&mut self.values).insert(key.to_owned(), value);
}
pub(crate) fn remove(&mut self, key: &str) {
if self.values.contains_key(key) {
Arc::make_mut(&mut self.values).remove(key);
}
}
pub(crate) fn overlay(&mut self, other: &Self) {
if other.values.is_empty() {
return;
}
let values = Arc::make_mut(&mut self.values);
for (key, value) in other.values.iter() {
values.insert(key.clone(), *value);
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub(crate) enum RawProp {
Expr(Expr),
Flag(bool),
Cells(u16),
Pair(u16, u16),
Word(&'static str),
}