Skip to main content

apace_dom/node/
attributes.rs

1use std::ops::{Deref, DerefMut};
2
3use markup5ever::QualName;
4use thin_vec::ThinVec;
5
6/// A tag attribute, e.g. `class="test"` in `<div class="test" ...>`.
7#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug)]
8pub struct Attribute {
9    /// The name of the attribute (e.g. the `class` in `<div class="test">`)
10    pub name: QualName,
11    /// The value of the attribute (e.g. the `"test"` in `<div class="test">`)
12    pub value: String,
13}
14
15#[derive(Clone, Debug)]
16pub struct Attributes {
17    inner: ThinVec<Attribute>,
18}
19
20impl Attributes {
21    pub fn new(inner: Vec<Attribute>) -> Self {
22        Self {
23            inner: inner.into_iter().collect(),
24        }
25    }
26
27    pub fn get(&mut self, name: &QualName) -> Option<&Attribute> {
28        self.inner.iter().find(|attr| attr.name == *name)
29    }
30
31    pub fn set(&mut self, name: QualName, value: &str) {
32        let existing_attr = self.inner.iter_mut().find(|a| a.name == name);
33        if let Some(existing_attr) = existing_attr {
34            existing_attr.value.clear();
35            existing_attr.value.push_str(value);
36        } else {
37            self.push(Attribute {
38                name: name.clone(),
39                value: value.to_string(),
40            });
41        }
42    }
43
44    pub fn remove(&mut self, name: &QualName) -> Option<Attribute> {
45        let idx = self.inner.iter().position(|attr| attr.name == *name);
46        idx.map(|idx| self.inner.remove(idx))
47    }
48}
49
50impl Deref for Attributes {
51    type Target = ThinVec<Attribute>;
52    fn deref(&self) -> &Self::Target {
53        &self.inner
54    }
55}
56impl DerefMut for Attributes {
57    fn deref_mut(&mut self) -> &mut Self::Target {
58        &mut self.inner
59    }
60}