tablo_test/protocol/
search.rs1use super::dom::{attr_value, strip_text, tags_where};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct SearchGroup {
11 pub label: String,
13 pub results: Vec<SearchResult>,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct SearchResult {
19 pub title: String,
20 pub href: String,
22 pub details: Vec<(String, String)>,
24}
25
26pub fn search_results(html: &str) -> Vec<SearchGroup> {
29 tags_where(html, |tag, attrs| {
30 tag == "section" && attr_value(attrs, "data-search-group").is_some()
31 })
32 .into_iter()
33 .map(|(_, attrs, inner)| SearchGroup {
34 label: attr_value(&attrs, "data-search-group").unwrap_or_default(),
35 results: tags_where(&inner, |tag, attrs| {
36 tag == "a" && attr_value(attrs, "data-search-hit").is_some()
37 })
38 .into_iter()
39 .map(|(_, attrs, inner)| SearchResult {
40 title: tags_where(&inner, |tag, _| tag == "span")
41 .first()
42 .map(|(_, _, text)| strip_text(text))
43 .unwrap_or_default(),
44 href: attr_value(&attrs, "href").unwrap_or_default(),
45 details: tags_where(&inner, |tag, _| tag == "dt")
46 .into_iter()
47 .zip(tags_where(&inner, |tag, _| tag == "dd"))
48 .map(|((_, _, label), (_, _, value))| {
49 (
50 strip_text(&label).trim_end_matches(':').to_string(),
51 strip_text(&value),
52 )
53 })
54 .collect(),
55 })
56 .collect(),
57 })
58 .collect()
59}
60
61pub fn search_box(html: &str) -> Option<String> {
63 let (_, _, inner) = tags_where(html, |tag, attrs| {
64 tag == "div" && attr_value(attrs, "data-global-search").is_some()
65 })
66 .into_iter()
67 .next()?;
68 tags_where(&inner, |tag, _| tag == "form")
69 .first()
70 .and_then(|(_, attrs, _)| attr_value(attrs, "action"))
71}