aboutsummaryrefslogtreecommitdiff
path: root/src/attr.rs
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2023-08-16 15:58:48 +0200
committerMartin Fischer <martin@push-f.com>2023-08-19 13:41:55 +0200
commit0c87a9ec25a45efc9b6b5ab7883cd19ded483909 (patch)
tree9db078c6f5b6f689ae406d8cce9625451bbcbbd1 /src/attr.rs
parent65aca9cbf0318bd3a2f936641b4f5bc3729c98c2 (diff)
feat: impl IntoIterator for AttributeMap
Making this change made me realize that adding an `impl IntoIterator for T` can be a breaking change if `impl IntoIterator for &T` already exists. See also the cargo-semver-checks issue[1] I filed about that. [1]: https://github.com/obi1kenobi/cargo-semver-checks/issues/518
Diffstat (limited to 'src/attr.rs')
-rw-r--r--src/attr.rs40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/attr.rs b/src/attr.rs
index 9e4c984..a56eb95 100644
--- a/src/attr.rs
+++ b/src/attr.rs
@@ -41,6 +41,19 @@ pub struct Attribute<'a, O> {
map_val: &'a AttrInternal<O>,
}
+/// An owned HTML attribute.
+#[derive(Debug, PartialEq, Eq)]
+pub struct AttributeOwned<O> {
+ /// The attribute name.
+ pub name: String,
+ /// The attribute value.
+ pub value: String,
+ /// The start offset of the attribute name.
+ pub name_offset: O,
+ /// The start offset of the attribute value.
+ pub value_offset: O, // TODO: wrap this in an Option once we can recognize the empty attribute syntax
+}
+
impl<O> AttributeMap<O> {
/// Returns the attribute with the given name.
pub fn get(&self, name: &str) -> Option<Attribute<O>> {
@@ -82,6 +95,33 @@ impl<O> Index<&str> for AttributeMap<O> {
}
}
+impl<O> IntoIterator for AttributeMap<O> {
+ type Item = AttributeOwned<O>;
+
+ type IntoIter = AttrIntoIter<O>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ AttrIntoIter(self.inner.into_iter())
+ }
+}
+
+/// A consuming iterator over the attributes of an [`AttributeMap`].
+pub struct AttrIntoIter<O>(btree_map::IntoIter<String, AttrInternal<O>>);
+
+impl<O> Iterator for AttrIntoIter<O> {
+ type Item = AttributeOwned<O>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let (name, map_val) = self.0.next()?;
+ Some(AttributeOwned {
+ name,
+ value: map_val.value,
+ name_offset: map_val.name_offset,
+ value_offset: map_val.value_offset,
+ })
+ }
+}
+
impl<'a, O> IntoIterator for &'a AttributeMap<O> {
type Item = Attribute<'a, O>;