Skip to main content

textlane_html/actions/attribute/
read.rs

1use std::borrow::Cow;
2
3use textlane_core::hast::{Element, PropertyItem, PropertyValue};
4
5use crate::actions::hast::stringify::write_js_number;
6use crate::helpers::property::find_property;
7use crate::helpers::schema::{HTML, SPACE_SEPARATED};
8use crate::helpers::value::{find_value, write_value};
9
10/// An attribute's value by its HTML name (`class`, `data-title`), as the HTML would spell
11/// it: `""` for a set boolean, `None` when unset, `false` or `null`.
12pub fn read_attribute<'a>(element: &Element<'a>, name: &str) -> Option<Cow<'a, str>> {
13    let found = find_property(&HTML, name);
14    match find_value(element, &found.property)? {
15        PropertyValue::Null | PropertyValue::Boolean(false) => None,
16        PropertyValue::Boolean(true) => Some(Cow::Borrowed("")),
17        PropertyValue::List(items) if found.kinds & SPACE_SEPARATED != 0 => {
18            let words: Vec<Cow<str>> = (items.iter())
19                .map(|item| match item {
20                    PropertyItem::String(word) => Cow::Borrowed(*word),
21                    PropertyItem::Number(number) => Cow::Owned(write_js_number(*number)),
22                })
23                .collect();
24            Some(Cow::Owned(words.join(" ")))
25        }
26        value => Some(write_value(value)),
27    }
28}
29
30#[cfg(test)]
31#[path = "read_unit.rs"]
32mod unit;