Skip to main content

tablo_test/protocol/
detail.rs

1//! Reads a detail page's entries, where `data-entry` names the column each one shows, and a
2//! record's navigation.
3
4use super::dom::{attr_value, strip_text, tags_where};
5
6/// One entry of a detail page.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct DetailEntry {
9    /// The name of the column the entry shows.
10    pub column: String,
11    /// The entry's text: its label, then its value.
12    pub text: String,
13}
14
15/// The entries a detail page renders, in document order, a nested block's in its place.
16pub fn detail_entries(html: &str) -> Vec<DetailEntry> {
17    tags_where(html, |_, attrs| attr_value(attrs, "data-entry").is_some())
18        .into_iter()
19        .map(|(_, attrs, inner)| DetailEntry {
20            column: attr_value(&attrs, "data-entry").unwrap_or_default(),
21            text: strip_text(&inner),
22        })
23        .collect()
24}
25
26/// One tab of a record's navigation.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub struct RecordNavLink {
29    /// Where the tab links.
30    pub href: String,
31    /// Whether the page is the tab's.
32    pub current: bool,
33}
34
35/// The tabs of the navigation a record's page renders, in document order: each tab's
36/// `data-record-nav`, and whether `aria-current` marks it. Empty without a navigation.
37pub fn record_navigation(html: &str) -> Vec<RecordNavLink> {
38    tags_where(html, |_, attrs| {
39        attr_value(attrs, "data-record-nav").is_some()
40    })
41    .into_iter()
42    .map(|(_, attrs, _)| RecordNavLink {
43        href: attr_value(&attrs, "data-record-nav").unwrap_or_default(),
44        current: attr_value(&attrs, "aria-current").as_deref() == Some("page"),
45    })
46    .collect()
47}