blob: 3ab88a77eac29043568f54b9629b833caafbe4fd [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::{Hash, HASH_SIZE};
/// Iterator over all 2^256 possible hash values. Not expected to be useful outside of tests.
#[derive(Debug)]
pub struct HashRangeFull(Option<[u8; HASH_SIZE]>);
impl Default for HashRangeFull {
fn default() -> Self {
Self(Some([0; HASH_SIZE]))
}
}
impl Iterator for HashRangeFull {
type Item = Hash;
fn next(&mut self) -> Option<Self::Item> {
fn inc(mut bignum: [u8; HASH_SIZE]) -> Option<[u8; HASH_SIZE]> {
let mut bytes = bignum.iter_mut().rev();
loop {
let n = bytes.next()?;
let (next, overflowed) = n.overflowing_add(1);
*n = next;
if !overflowed {
break;
}
}
Some(bignum)
}
match self.0 {
Some(bytes) => {
let res = Hash::from(bytes);
self.0 = inc(bytes);
Some(res)
}
None => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hash_range_full() {
let mut iter = HashRangeFull::default();
assert_eq!(
iter.next(),
Some(Hash::from([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
]))
);
assert_eq!(
iter.next(),
Some(Hash::from([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1
]))
);
assert_eq!(
HashRangeFull::default().nth(256),
Some(Hash::from([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0
]))
);
}
#[test]
fn hash_range_full_ends() {
let mut iter = HashRangeFull(Some([255; HASH_SIZE]));
assert_eq!(iter.next(), Some(Hash::from([255; HASH_SIZE])));
assert_eq!(iter.next(), None);
}
}