Skip to content

Commit

Permalink
Implement IntoIterator for Array
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Jun 11, 2023
1 parent 5f10d6f commit 36e20b1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

## [Unreleased](https://github.com/rustwasm/wasm-bindgen/compare/0.2.86...main)

### Added

* Implemented `IntoIterator` for `Array`.
[#3477](https://github.com/rustwasm/wasm-bindgen/pull/3477)

### Changed

* Deprecate `HtmlMenuItemElement` and parts of `HtmlMenuElement`.
Expand Down
96 changes: 96 additions & 0 deletions crates/js-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,64 @@ extern "C" {
pub fn unshift(this: &Array, value: &JsValue) -> u32;
}

/// Iterator returned by `Array::into_iter`
#[derive(Debug, Clone)]
pub struct ArrayIntoIter {
range: std::ops::Range<u32>,
array: Array,
}

impl std::iter::Iterator for ArrayIntoIter {
type Item = JsValue;

fn next(&mut self) -> Option<Self::Item> {
let index = self.range.next()?;
Some(self.array.get(index))
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}

#[inline]
fn count(self) -> usize
where
Self: Sized,
{
self.range.count()
}

#[inline]
fn last(self) -> Option<Self::Item>
where
Self: Sized,
{
let Self { range, array } = self;
range.last().map(|index| array.get(index))
}

#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth(n).map(|index| self.array.get(index))
}
}

impl std::iter::DoubleEndedIterator for ArrayIntoIter {
fn next_back(&mut self) -> Option<Self::Item> {
let index = self.range.next_back()?;
Some(self.array.get(index))
}

fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth_back(n).map(|index| self.array.get(index))
}
}

impl std::iter::FusedIterator for ArrayIntoIter {}

impl std::iter::ExactSizeIterator for ArrayIntoIter {}

/// Iterator returned by `Array::iter`
#[derive(Debug, Clone)]
pub struct ArrayIter<'a> {
Expand All @@ -629,13 +687,39 @@ impl<'a> std::iter::Iterator for ArrayIter<'a> {
fn size_hint(&self) -> (usize, Option<usize>) {
self.range.size_hint()
}

#[inline]
fn count(self) -> usize
where
Self: Sized,
{
self.range.count()
}

#[inline]
fn last(self) -> Option<Self::Item>
where
Self: Sized,
{
let Self { range, array } = self;
range.last().map(|index| array.get(index))
}

#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth(n).map(|index| self.array.get(index))
}
}

impl<'a> std::iter::DoubleEndedIterator for ArrayIter<'a> {
fn next_back(&mut self) -> Option<Self::Item> {
let index = self.range.next_back()?;
Some(self.array.get(index))
}

fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.range.nth_back(n).map(|index| self.array.get(index))
}
}

impl<'a> std::iter::FusedIterator for ArrayIter<'a> {}
Expand Down Expand Up @@ -665,6 +749,18 @@ impl Array {
}
}

impl std::iter::IntoIterator for Array {
type Item = JsValue;
type IntoIter = ArrayIntoIter;

fn into_iter(self) -> Self::IntoIter {
ArrayIntoIter {
range: 0..self.length(),
array: self,
}
}
}

// TODO pre-initialize the Array with the correct length using TrustedLen
impl<A> std::iter::FromIterator<A> for Array
where
Expand Down

0 comments on commit 36e20b1

Please sign in to comment.