use crate::core::TextHandler;
use crate::parser::selector::Selector;
#[derive(Debug, Clone)]
pub struct Selectors {
items: Vec<Selector>,
}
impl Selectors {
pub fn new(items: Vec<Selector>) -> Self {
Self { items }
}
#[must_use]
pub fn len(&self) -> usize {
self.items.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
#[must_use]
pub fn first(&self) -> Option<&Selector> {
self.items.first()
}
#[must_use]
pub fn last(&self) -> Option<&Selector> {
self.items.last()
}
#[must_use]
pub fn css(&self, selector: &str) -> Selectors {
let items: Vec<Selector> = self
.items
.iter()
.flat_map(|s| s.css(selector).into_iter())
.collect();
Selectors::new(items)
}
#[must_use]
pub fn re(
&self,
pattern: &str,
replace_entities: bool,
clean_match: bool,
case_sensitive: bool,
) -> Vec<TextHandler> {
self.items
.iter()
.flat_map(|s| s.re(pattern, replace_entities, clean_match, case_sensitive))
.collect()
}
#[must_use]
pub fn re_first(
&self,
pattern: &str,
replace_entities: bool,
clean_match: bool,
case_sensitive: bool,
) -> Option<TextHandler> {
for s in &self.items {
if let Some(m) = s.re_first(pattern, replace_entities, clean_match, case_sensitive) {
return Some(m);
}
}
None
}
#[must_use]
pub fn get_first(&self, default: Option<TextHandler>) -> Option<TextHandler> {
self.items
.first()
.map(|s| s.get_all_text("", true, &[], None))
.or(default)
}
#[must_use]
pub fn getall(&self) -> Vec<TextHandler> {
self.items
.iter()
.map(|s| s.get_all_text("", true, &[], None))
.collect()
}
#[must_use]
pub fn search<F>(&self, func: F) -> Option<&Selector>
where
F: Fn(&Selector) -> bool,
{
self.items.iter().find(|s| func(s))
}
#[must_use]
pub fn filter<F>(&self, func: F) -> Selectors
where
F: Fn(&Selector) -> bool,
{
let items: Vec<Selector> = self.items.iter().filter(|s| func(s)).cloned().collect();
Selectors::new(items)
}
}
impl std::ops::Index<usize> for Selectors {
type Output = Selector;
fn index(&self, index: usize) -> &Self::Output {
&self.items[index]
}
}
impl IntoIterator for Selectors {
type Item = Selector;
type IntoIter = std::vec::IntoIter<Selector>;
fn into_iter(self) -> Self::IntoIter {
self.items.into_iter()
}
}
impl<'a> IntoIterator for &'a Selectors {
type Item = &'a Selector;
type IntoIter = std::slice::Iter<'a, Selector>;
fn into_iter(self) -> Self::IntoIter {
self.items.iter()
}
}