Skip to content

Commit

Permalink
Add clear and drain implementations to Attributes (rojo-rbx#409)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dekkonot authored May 6, 2024
1 parent ddba210 commit ff994c3
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
2 changes: 2 additions & 0 deletions rbx_types/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
## Unreleased Changes
* Implement `IntoIterator` for `&Attributes`. ([#386])
* Implement `Extend<(String, Variant)>` for `Attributes`. ([#386])
* Implement `clear` and `drain` for `Attributes`. ([#409])

[#386]: https://github.com/rojo-rbx/rbx-dom/pull/386
[#409]: https://github.com/rojo-rbx/rbx-dom/pull/409

## 1.8.0 (2024-01-16)
* Add `len` and `is_empty` methods to `Attributes` struct. ([#377])
Expand Down
57 changes: 57 additions & 0 deletions rbx_types/src/attributes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ impl Attributes {
self.data.remove(key.borrow())
}

/// Removes all attributes.
#[inline]
pub fn clear(&mut self) {
self.data.clear()
}

/// Returns an iterator of borrowed attributes.
#[inline]
pub fn iter(&self) -> AttributesIter<'_> {
Expand All @@ -82,6 +88,14 @@ impl Attributes {
}
}

/// Removes all elements from the `Attributes`, returning them as an
/// iterator. If the iterator is dropped before being fully consumed,
/// it drops the remaining removed elements.
#[inline]
pub fn drain(&mut self) -> AttributesDrain<'_> {
AttributesDrain { inner: self }
}

/// Returns the number of attributes.
#[inline]
pub fn len(&self) -> usize {
Expand Down Expand Up @@ -159,6 +173,28 @@ impl<'a> Iterator for AttributesIter<'a> {
}
}

/// A draining iterator for `Attributes`.
/// This is created by [`Attributes::drain`].
///
/// If dropped before fully used, all remaining values will be dropped.
pub struct AttributesDrain<'a> {
inner: &'a mut Attributes,
}

impl<'a> Iterator for AttributesDrain<'a> {
type Item = (String, Variant);

fn next(&mut self) -> Option<Self::Item> {
self.inner.data.pop_first()
}
}

impl<'a> Drop for AttributesDrain<'a> {
fn drop(&mut self) {
self.inner.clear()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -231,4 +267,25 @@ mod tests {
attributes.insert("key".to_owned(), Variant::Bool(true));
assert_eq!(attributes.remove("key"), Some(Variant::Bool(true)));
}

#[test]
fn attribute_drain() {
let mut attributes = Attributes::new();
attributes.extend([
("string".into(), "value".into()),
("float64".into(), 10.0_f64.into()),
("bool".into(), true.into()),
]);
assert!(!attributes.is_empty());

let mut map = BTreeMap::new();
for (key, value) in attributes.drain() {
map.insert(key, value);
}

assert_eq!(map.get("string"), Some(&Variant::String("value".into())));
assert_eq!(map.get("float64"), Some(&Variant::Float64(10.0)));
assert_eq!(map.get("bool"), Some(&Variant::Bool(true)));
assert!(attributes.is_empty());
}
}

0 comments on commit ff994c3

Please sign in to comment.