use {
crate::hash_singleton::SingletonHashTrieIter,
kermit_iters::{HashTrieIterable, HashTrieIterator, JoinIterable},
};
pub enum HashTrieIterKind<'a, R: HashTrieIterable> {
Relation(&'a R),
Singleton(SingletonHashTrieIter),
}
pub enum HashKindIter<IT>
where
IT: HashTrieIterator,
{
Relation(IT),
Singleton(SingletonHashTrieIter),
}
impl<IT> HashTrieIterator for HashKindIter<IT>
where
IT: HashTrieIterator,
{
fn key(&self) -> Option<u64> {
match self {
| Self::Relation(it) => it.key(),
| Self::Singleton(it) => it.key(),
}
}
fn next(&mut self) -> Option<u64> {
match self {
| Self::Relation(it) => it.next(),
| Self::Singleton(it) => it.next(),
}
}
fn lookup(&mut self, hash: u64) -> bool {
match self {
| Self::Relation(it) => it.lookup(hash),
| Self::Singleton(it) => it.lookup(hash),
}
}
fn size(&self) -> usize {
match self {
| Self::Relation(it) => it.size(),
| Self::Singleton(it) => it.size(),
}
}
fn at_end(&self) -> bool {
match self {
| Self::Relation(it) => it.at_end(),
| Self::Singleton(it) => it.at_end(),
}
}
fn open(&mut self) -> bool {
match self {
| Self::Relation(it) => it.open(),
| Self::Singleton(it) => it.open(),
}
}
fn up(&mut self) -> bool {
match self {
| Self::Relation(it) => it.up(),
| Self::Singleton(it) => it.up(),
}
}
fn leaf_tuples(&self) -> Option<&[Vec<usize>]> {
match self {
| Self::Relation(it) => it.leaf_tuples(),
| Self::Singleton(it) => it.leaf_tuples(),
}
}
}
impl<R: HashTrieIterable> JoinIterable for HashTrieIterKind<'_, R> {}
impl<R: HashTrieIterable> HashTrieIterable for HashTrieIterKind<'_, R> {
fn hash_trie_iter(&self) -> impl HashTrieIterator {
match self {
| Self::Relation(r) => HashKindIter::Relation(r.hash_trie_iter()),
| Self::Singleton(s) => HashKindIter::Singleton(s.clone()),
}
}
}
#[cfg(test)]
mod tests {
use {
super::*,
kermit_ds::{HashTrie, Relation},
};
#[test]
fn relation_variant_delegates_open() {
let r = HashTrie::from_tuples(2.into(), vec![vec![1, 2]]);
let kind: HashTrieIterKind<HashTrie> = HashTrieIterKind::Relation(&r);
let mut it = kind.hash_trie_iter();
assert!(it.open());
}
#[test]
fn singleton_variant_delegates_key() {
use kermit_iters::{HashStrategy, SipHashStrategy};
let hash = SipHashStrategy::hash(7);
let kind: HashTrieIterKind<HashTrie> =
HashTrieIterKind::Singleton(SingletonHashTrieIter::new(7, hash));
let mut it = kind.hash_trie_iter();
assert!(it.open());
assert_eq!(it.key(), Some(hash));
}
}