From c1939cd56218ac7afe053ea062052f79468b0cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Grzegorz=20=C5=9Awirski?= Date: Wed, 16 Apr 2025 17:47:33 +0200 Subject: [PATCH] use Cow instead of the additional IntoIter struct --- miden-crypto/src/merkle/sparse_path.rs | 71 +++++++------------------- 1 file changed, 18 insertions(+), 53 deletions(-) diff --git a/miden-crypto/src/merkle/sparse_path.rs b/miden-crypto/src/merkle/sparse_path.rs index a918510..32ba2d6 100644 --- a/miden-crypto/src/merkle/sparse_path.rs +++ b/miden-crypto/src/merkle/sparse_path.rs @@ -1,4 +1,4 @@ -use alloc::vec::Vec; +use alloc::{borrow::Cow, vec::Vec}; use core::{ iter::{self, FusedIterator}, num::NonZero, @@ -252,20 +252,10 @@ impl From for Vec { // ITERATORS // ================================================================================================ -impl<'p> IntoIterator for &'p SparseMerklePath { - type Item = 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`]. +/// Iterator for [`SparseMerklePath`]. pub struct SparseMerklePathIter<'p> { /// 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 /// exhausted. @@ -306,57 +296,32 @@ impl FusedIterator for SparseMerklePathIter<'_> {} // 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 { - type IntoIter = IntoIter; + type IntoIter = SparseMerklePathIter<'static>; type Item = ::Item; - fn into_iter(self) -> IntoIter { + fn into_iter(self) -> SparseMerklePathIter<'static> { 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 { - type Item = RpoDigest; +impl<'p> IntoIterator for &'p SparseMerklePath { + type Item = as Iterator>::Item; + type IntoIter = SparseMerklePathIter<'p>; - fn next(&mut self) -> Option { - let this_depth = self.next_depth; - // Paths don't include the root, so if `this_depth` is 0 then we keep returning `None`. - let this_depth = NonZero::new(this_depth)?; - self.next_depth = this_depth.get() - 1; - - // `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) { - let remaining = ExactSizeIterator::len(self); - (remaining, Some(remaining)) + fn into_iter(self) -> SparseMerklePathIter<'p> { + let tree_depth = self.depth(); + SparseMerklePathIter { + path: Cow::Borrowed(self), + next_depth: tree_depth, + } } } -impl ExactSizeIterator for IntoIter { - fn len(&self) -> usize { - self.next_depth as usize - } -} - -impl FusedIterator for IntoIter {} - -// TODO: impl DoubleEndedIterator. - // COMPARISONS // ================================================================================================ impl PartialEq for SparseMerklePath {