Skip to content

Commit 673e3eb

Browse files
committed
Implement IntoIterator for Array
1 parent 5f10d6f commit 673e3eb

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

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

6+
### Added
7+
8+
* Implemented `IntoIterator` for `Array`.
9+
[#3477](https://github.com/rustwasm/wasm-bindgen/pull/3477)
10+
611
### Changed
712

813
* Deprecate `HtmlMenuItemElement` and parts of `HtmlMenuElement`.

crates/js-sys/src/lib.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,64 @@ extern "C" {
610610
pub fn unshift(this: &Array, value: &JsValue) -> u32;
611611
}
612612

613+
/// Iterator returned by `Array::into_iter`
614+
#[derive(Debug, Clone)]
615+
pub struct ArrayIntoIter {
616+
range: std::ops::Range<u32>,
617+
array: Array,
618+
}
619+
620+
impl std::iter::Iterator for ArrayIntoIter {
621+
type Item = JsValue;
622+
623+
fn next(&mut self) -> Option<Self::Item> {
624+
let index = self.range.next()?;
625+
Some(self.array.get(index))
626+
}
627+
628+
#[inline]
629+
fn size_hint(&self) -> (usize, Option<usize>) {
630+
self.range.size_hint()
631+
}
632+
633+
#[inline]
634+
fn count(self) -> usize
635+
where
636+
Self: Sized,
637+
{
638+
self.range.count()
639+
}
640+
641+
#[inline]
642+
fn last(self) -> Option<Self::Item>
643+
where
644+
Self: Sized,
645+
{
646+
let Self { range, array } = self;
647+
range.last().map(|index| array.get(index))
648+
}
649+
650+
#[inline]
651+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
652+
self.range.nth(n).map(|index| self.array.get(index))
653+
}
654+
}
655+
656+
impl std::iter::DoubleEndedIterator for ArrayIntoIter {
657+
fn next_back(&mut self) -> Option<Self::Item> {
658+
let index = self.range.next_back()?;
659+
Some(self.array.get(index))
660+
}
661+
662+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
663+
self.range.nth_back(n).map(|index| self.array.get(index))
664+
}
665+
}
666+
667+
impl std::iter::FusedIterator for ArrayIntoIter {}
668+
669+
impl std::iter::ExactSizeIterator for ArrayIntoIter {}
670+
613671
/// Iterator returned by `Array::iter`
614672
#[derive(Debug, Clone)]
615673
pub struct ArrayIter<'a> {
@@ -629,13 +687,39 @@ impl<'a> std::iter::Iterator for ArrayIter<'a> {
629687
fn size_hint(&self) -> (usize, Option<usize>) {
630688
self.range.size_hint()
631689
}
690+
691+
#[inline]
692+
fn count(self) -> usize
693+
where
694+
Self: Sized,
695+
{
696+
self.range.count()
697+
}
698+
699+
#[inline]
700+
fn last(self) -> Option<Self::Item>
701+
where
702+
Self: Sized,
703+
{
704+
let Self { range, array } = self;
705+
range.last().map(|index| array.get(index))
706+
}
707+
708+
#[inline]
709+
fn nth(&mut self, n: usize) -> Option<Self::Item> {
710+
self.range.nth(n).map(|index| self.array.get(index))
711+
}
632712
}
633713

634714
impl<'a> std::iter::DoubleEndedIterator for ArrayIter<'a> {
635715
fn next_back(&mut self) -> Option<Self::Item> {
636716
let index = self.range.next_back()?;
637717
Some(self.array.get(index))
638718
}
719+
720+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
721+
self.range.nth_back(n).map(|index| self.array.get(index))
722+
}
639723
}
640724

641725
impl<'a> std::iter::FusedIterator for ArrayIter<'a> {}
@@ -665,6 +749,18 @@ impl Array {
665749
}
666750
}
667751

752+
impl std::iter::IntoIterator for Array {
753+
type Item = JsValue;
754+
type IntoIter = ArrayIntoIter;
755+
756+
fn into_iter(self) -> Self::IntoIter {
757+
ArrayIntoIter {
758+
range: 0..self.length(),
759+
array: self,
760+
}
761+
}
762+
}
763+
668764
// TODO pre-initialize the Array with the correct length using TrustedLen
669765
impl<A> std::iter::FromIterator<A> for Array
670766
where

0 commit comments

Comments
 (0)