Skip to main content

tablo_test/protocol/
ignored.rs

1//! Reads a table's ignored-filters banner: each entry's `data-ignored-filter` names the filter as
2//! the request spelled it, and its `data-ignored` names why.
3
4use tablo_core::dom::ignored;
5
6use super::dom::{attr_value, tags_where};
7
8/// A requested filter the table did not apply.
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct IgnoredFilter {
11    /// The filter's parameters as the request spelled them, such as `f.status=draft`.
12    pub filter: String,
13    /// Why the table ignored it.
14    pub reason: IgnoredReason,
15}
16
17/// Why a table ignored a requested filter, as the banner's `data-ignored` names it.
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19#[non_exhaustive]
20pub enum IgnoredReason {
21    /// The table declares no filter of that name.
22    Unknown,
23    /// The filter selects nothing by the value, or refuses it, as it refuses a key naming a
24    /// record the user may not see: the two read alike.
25    Invalid,
26    /// The request carried more filters, values or bytes than the table reads.
27    Dropped,
28}
29
30/// The filters the banner of `html` lists as ignored, in its order; empty without a banner.
31///
32/// # Panics
33///
34/// When an entry names no reason this version knows: a renderer that drops `data-ignored`'s
35/// value would otherwise read as any reason.
36pub fn ignored_filters(html: &str) -> Vec<IgnoredFilter> {
37    tags_where(html, |_, attrs| {
38        attr_value(attrs, "data-ignored-filter").is_some()
39    })
40    .into_iter()
41    .filter_map(|(_, attrs, _)| {
42        let filter = attr_value(&attrs, "data-ignored-filter")?;
43        let reason = match attr_value(&attrs, "data-ignored").as_deref() {
44            Some(ignored::UNKNOWN) => IgnoredReason::Unknown,
45            Some(ignored::INVALID) => IgnoredReason::Invalid,
46            Some(ignored::DROPPED) => IgnoredReason::Dropped,
47            other => panic!("the ignored filter names no known reason: {other:?}"),
48        };
49        Some(IgnoredFilter { filter, reason })
50    })
51    .collect()
52}