use Cow instead of the additional IntoIter struct

This commit is contained in:
Grzegorz Świrski 2025-04-16 17:47:33 +02:00 committed by Qyriad
parent c236589b5e
commit 00eea2516f

View file

@ -1,4 +1,4 @@
use alloc::vec::Vec; use alloc::{borrow::Cow, vec::Vec};
use core::{ use core::{
iter::{self, FusedIterator}, iter::{self, FusedIterator},
num::NonZero, num::NonZero,
@ -252,20 +252,10 @@ impl From<SparseMerklePath> for Vec<RpoDigest> {
// ITERATORS // ITERATORS
// ================================================================================================ // ================================================================================================
impl<'p> IntoIterator for &'p SparseMerklePath { /// Iterator for [`SparseMerklePath`].
type Item = <SparseMerklePathIter<'p> as Iterator>::Item;
type IntoIter = SparseMerklePathIter<'p>;
fn into_iter(self) -> SparseMerklePathIter<'p> {
let tree_depth = self.depth();
SparseMerklePathIter { path: self, next_depth: tree_depth }
}
}
/// Borrowing iterator for [`SparseMerklePath`].
pub struct SparseMerklePathIter<'p> { pub struct SparseMerklePathIter<'p> {
/// The "inner" value we're iterating over. /// The "inner" value we're iterating over.
path: &'p SparseMerklePath, path: Cow<'p, SparseMerklePath>,
/// The depth a `next()` call will get. `next_depth == 0` indicates that the iterator has been /// The depth a `next()` call will get. `next_depth == 0` indicates that the iterator has been
/// exhausted. /// exhausted.
@ -306,57 +296,32 @@ impl FusedIterator for SparseMerklePathIter<'_> {}
// TODO: impl DoubleEndedIterator. // TODO: impl DoubleEndedIterator.
/// Owning iterator for [SparseMerklePath].
pub struct IntoIter {
/// The "inner" value we're iterating over.
path: SparseMerklePath,
/// The depth a `next()` call will get. `next_depth == 0` indicates that the iterator has been
/// exhausted.
next_depth: u8,
}
impl IntoIterator for SparseMerklePath { impl IntoIterator for SparseMerklePath {
type IntoIter = IntoIter; type IntoIter = SparseMerklePathIter<'static>;
type Item = <Self::IntoIter as Iterator>::Item; type Item = <Self::IntoIter as Iterator>::Item;
fn into_iter(self) -> IntoIter { fn into_iter(self) -> SparseMerklePathIter<'static> {
let tree_depth = self.depth(); let tree_depth = self.depth();
IntoIter { path: self, next_depth: tree_depth } SparseMerklePathIter {
path: Cow::Owned(self),
next_depth: tree_depth,
}
} }
} }
impl Iterator for IntoIter { impl<'p> IntoIterator for &'p SparseMerklePath {
type Item = RpoDigest; type Item = <SparseMerklePathIter<'p> as Iterator>::Item;
type IntoIter = SparseMerklePathIter<'p>;
fn next(&mut self) -> Option<RpoDigest> { fn into_iter(self) -> SparseMerklePathIter<'p> {
let this_depth = self.next_depth; let tree_depth = self.depth();
// Paths don't include the root, so if `this_depth` is 0 then we keep returning `None`. SparseMerklePathIter {
let this_depth = NonZero::new(this_depth)?; path: Cow::Borrowed(self),
self.next_depth = this_depth.get() - 1; next_depth: tree_depth,
}
// `this_depth` is only ever decreasing, so it can't ever exceed `self.path.depth()`.
let node = self.path.at_depth(this_depth).unwrap();
Some(node)
}
// IntoIter always knows its exact size.
fn size_hint(&self) -> (usize, Option<usize>) {
let remaining = ExactSizeIterator::len(self);
(remaining, Some(remaining))
} }
} }
impl ExactSizeIterator for IntoIter {
fn len(&self) -> usize {
self.next_depth as usize
}
}
impl FusedIterator for IntoIter {}
// TODO: impl DoubleEndedIterator.
// COMPARISONS // COMPARISONS
// ================================================================================================ // ================================================================================================
impl PartialEq<MerklePath> for SparseMerklePath { impl PartialEq<MerklePath> for SparseMerklePath {