pub trait SelectorBase { fn from_html(html: String) -> Self; fn html(&self) -> String; // fn css<'a, T: SelectorBase>(&self, css_selector: &'a str) -> Vec { fn css<'a>(&self, css_selector: &'a str) -> Vec { let html = nipper::Document::from(self.html().as_str()); let mut output = vec![]; for item in html.select(css_selector).iter() { output.push(Selector::from_html(item.html().to_string())) } output } fn css_once<'a>(&self, css_selector: &'a str) -> Option { self.css(css_selector).pop() } fn xpath(&self, xpath: &'static str) -> Vec { match cssifier::cssifier(xpath) { Some(css_selector) => { if css_selector == "" { Vec::default() } else { self.css(css_selector.as_str()) } } None => Vec::default(), } } fn xpath_once(&self, xpath: &'static str) -> Option { self.xpath(xpath).pop() } fn content(&self) -> String { let html = nipper::Document::from(self.html().as_str()); html.select("body > *") .iter() .map(|element| element.text().to_string()) .last() .unwrap() } fn attr<'a>(&self, attribute: &'a str) -> Option { let html = nipper::Document::from(self.html().as_str()); match html.select("body > *").attr(attribute) { Some(text) => Some(format!("{}", text)), None => None, } } } #[derive(Debug)] pub struct Selector { text: String, } impl SelectorBase for Selector { fn from_html(html: String) -> Self { Selector { text: html.to_string(), } } fn html(&self) -> String { self.text.clone() } }