1use std::collections::BTreeMap;
4use std::sync::Arc;
5
6use super::paint::{Expr, Paint};
7
8#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum PropValue {
11 Paint(Paint),
13 Flag(bool),
15 Cells(u16),
17 Pair(u16, u16),
19 Word(&'static str),
22}
23
24pub const WORD_PROPS: [(&str, &str, &[&str]); 1] = [("scrollbar", "style", &["block", "half", "thin", "dots"])];
27
28pub(crate) fn allowed_words(widget: &str, key: &str) -> Option<&'static [&'static str]> {
30 WORD_PROPS.iter().find(|(w, k, _)| *w == widget && *k == key).map(|(_, _, words)| *words)
31}
32
33#[derive(Debug, Clone, Default, PartialEq)]
38pub struct StyleProps {
39 values: Arc<BTreeMap<String, PropValue>>,
40}
41
42impl StyleProps {
43 #[must_use]
45 pub fn get(&self, key: &str) -> Option<PropValue> {
46 self.values.get(key).copied()
47 }
48
49 #[must_use]
51 pub fn paint(&self, key: &str) -> Option<Paint> {
52 match self.get(key)? {
53 PropValue::Paint(paint) => Some(paint),
54 _ => None,
55 }
56 }
57
58 #[must_use]
60 pub fn flag(&self, key: &str) -> bool {
61 matches!(self.get(key), Some(PropValue::Flag(true)))
62 }
63
64 #[must_use]
66 pub fn cells(&self, key: &str) -> Option<u16> {
67 match self.get(key)? {
68 PropValue::Cells(n) => Some(n),
69 _ => None,
70 }
71 }
72
73 #[must_use]
75 pub fn pair(&self, key: &str) -> Option<(u16, u16)> {
76 match self.get(key)? {
77 PropValue::Pair(v, h) => Some((v, h)),
78 _ => None,
79 }
80 }
81
82 #[must_use]
84 pub fn word(&self, key: &str) -> Option<&'static str> {
85 match self.get(key)? {
86 PropValue::Word(word) => Some(word),
87 _ => None,
88 }
89 }
90
91 #[must_use]
93 pub fn is_animated(&self) -> bool {
94 self.values.values().any(|value| matches!(value, PropValue::Paint(paint) if paint.is_animated()))
95 }
96
97 #[must_use]
99 pub fn is_empty(&self) -> bool {
100 self.values.is_empty()
101 }
102
103 pub fn iter(&self) -> impl Iterator<Item = (&str, PropValue)> {
105 self.values.iter().map(|(key, value)| (key.as_str(), *value))
106 }
107
108 pub(crate) fn set(&mut self, key: &str, value: PropValue) {
109 Arc::make_mut(&mut self.values).insert(key.to_owned(), value);
110 }
111
112 pub(crate) fn remove(&mut self, key: &str) {
114 if self.values.contains_key(key) {
115 Arc::make_mut(&mut self.values).remove(key);
116 }
117 }
118
119 pub(crate) fn overlay(&mut self, other: &Self) {
121 if other.values.is_empty() {
122 return;
123 }
124 let values = Arc::make_mut(&mut self.values);
125 for (key, value) in other.values.iter() {
126 values.insert(key.clone(), *value);
127 }
128 }
129}
130
131#[derive(Debug, Clone, PartialEq)]
133pub(crate) enum RawProp {
134 Expr(Expr),
135 Flag(bool),
136 Cells(u16),
137 Pair(u16, u16),
138 Word(&'static str),
139}