iris_cssom/
cssrulelist.rs1use std::sync::{Arc, Mutex};
6use crate::cssrule::CSSRuleTrait;
7
8#[derive(Clone)]
27pub struct CSSRuleList {
28 rules: Vec<Arc<Mutex<dyn CSSRuleTrait>>>,
30}
31
32impl std::fmt::Debug for CSSRuleList {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("CSSRuleList")
35 .field("rules_count", &self.rules.len())
36 .finish()
37 }
38}
39
40impl CSSRuleList {
41 pub fn new() -> Self {
43 Self {
44 rules: Vec::new(),
45 }
46 }
47
48 pub fn from_rules(rules: Vec<Arc<Mutex<dyn CSSRuleTrait>>>) -> Self {
50 Self { rules }
51 }
52
53 pub fn length(&self) -> u32 {
64 self.rules.len() as u32
65 }
66
67 pub fn item(&self, index: u32) -> Option<Arc<Mutex<dyn CSSRuleTrait>>> {
92 if index < self.rules.len() as u32 {
93 Some(Arc::clone(&self.rules[index as usize]))
94 } else {
95 None
96 }
97 }
98
99 pub fn append_rule(&mut self, rule: Arc<Mutex<dyn CSSRuleTrait>>) {
105 self.rules.push(rule);
106 }
107
108 pub fn insert_rule(&mut self, rule: Arc<Mutex<dyn CSSRuleTrait>>, index: usize) -> bool {
119 if index > self.rules.len() {
120 return false;
121 }
122 self.rules.insert(index, rule);
123 true
124 }
125
126 pub fn remove_rule(&mut self, index: usize) -> bool {
136 if index < self.rules.len() {
137 self.rules.remove(index);
138 true
139 } else {
140 false
141 }
142 }
143
144 pub fn clear(&mut self) {
146 self.rules.clear();
147 }
148
149 pub fn iter(&self) -> impl Iterator<Item = &Arc<Mutex<dyn CSSRuleTrait>>> {
151 self.rules.iter()
152 }
153
154 pub fn get_all_css_texts(&self) -> Vec<String> {
173 self.rules
174 .iter()
175 .map(|r| r.lock().unwrap().get_css_text().to_string())
176 .collect()
177 }
178}
179
180impl Default for CSSRuleList {
181 fn default() -> Self {
182 Self::new()
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189 use crate::cssrule::CSSStyleRule;
190
191 #[test]
192 fn test_new_list() {
193 let list = CSSRuleList::new();
194 assert_eq!(list.length(), 0);
195 }
196
197 #[test]
198 fn test_append_rule() {
199 let mut list = CSSRuleList::new();
200 let rule = Arc::new(Mutex::new(CSSStyleRule::new(".class")));
201 list.append_rule(rule);
202 assert_eq!(list.length(), 1);
203 }
204
205 #[test]
206 fn test_item() {
207 let mut list = CSSRuleList::new();
208 let rule = Arc::new(Mutex::new(CSSStyleRule::new(".class")));
209 list.append_rule(rule.clone());
210
211 let retrieved = list.item(0);
212 assert!(retrieved.is_some());
213
214 let not_found = list.item(1);
215 assert!(not_found.is_none());
216 }
217
218 #[test]
219 fn test_insert_rule() {
220 let mut list = CSSRuleList::new();
221 let rule1 = Arc::new(Mutex::new(CSSStyleRule::new(".class1")));
222 let rule2 = Arc::new(Mutex::new(CSSStyleRule::new(".class2")));
223
224 list.append_rule(rule1);
225 list.insert_rule(rule2, 0); assert_eq!(list.length(), 2);
228 assert!(list.item(0).unwrap().lock().unwrap().get_css_text().contains(".class2"));
229 }
230
231 #[test]
232 fn test_remove_rule() {
233 let mut list = CSSRuleList::new();
234 let rule = Arc::new(Mutex::new(CSSStyleRule::new(".class")));
235 list.append_rule(rule);
236
237 assert!(list.remove_rule(0));
238 assert_eq!(list.length(), 0);
239
240 assert!(!list.remove_rule(0)); }
242
243 #[test]
244 fn test_clear() {
245 let mut list = CSSRuleList::new();
246 list.append_rule(Arc::new(Mutex::new(CSSStyleRule::new(".class1"))));
247 list.append_rule(Arc::new(Mutex::new(CSSStyleRule::new(".class2"))));
248
249 list.clear();
250 assert_eq!(list.length(), 0);
251 }
252
253 #[test]
254 fn test_get_all_css_texts() {
255 let mut list = CSSRuleList::new();
256 list.append_rule(Arc::new(Mutex::new(CSSStyleRule::new(".class1"))));
257 list.append_rule(Arc::new(Mutex::new(CSSStyleRule::new(".class2"))));
258
259 let texts = list.get_all_css_texts();
260 assert_eq!(texts.len(), 2);
261 assert!(texts[0].contains(".class1"));
262 assert!(texts[1].contains(".class2"));
263 }
264}