kermit_algos/
trie_iter_kind.rs1use {
6 crate::singleton::SingletonTrieIter,
7 kermit_iters::{JoinIterable, LinearIterator, TrieIterable, TrieIterator, TrieIteratorWrapper},
8};
9
10pub enum TrieIterKind<'a, R: TrieIterable> {
16 Relation(&'a R),
18 Singleton(SingletonTrieIter),
20}
21
22pub enum KindIter<IT>
25where
26 IT: TrieIterator,
27{
28 Relation(IT),
30 Singleton(SingletonTrieIter),
32}
33
34impl<IT> LinearIterator for KindIter<IT>
35where
36 IT: TrieIterator,
37{
38 fn key(&self) -> Option<usize> {
39 match self {
40 | Self::Relation(it) => it.key(),
41 | Self::Singleton(it) => it.key(),
42 }
43 }
44
45 fn next(&mut self) -> Option<usize> {
46 match self {
47 | Self::Relation(it) => it.next(),
48 | Self::Singleton(it) => it.next(),
49 }
50 }
51
52 fn seek(&mut self, seek_key: usize) -> bool {
53 match self {
54 | Self::Relation(it) => it.seek(seek_key),
55 | Self::Singleton(it) => it.seek(seek_key),
56 }
57 }
58
59 fn at_end(&self) -> bool {
60 match self {
61 | Self::Relation(it) => it.at_end(),
62 | Self::Singleton(it) => it.at_end(),
63 }
64 }
65}
66
67impl<IT> TrieIterator for KindIter<IT>
68where
69 IT: TrieIterator,
70{
71 fn open(&mut self) -> bool {
72 match self {
73 | Self::Relation(it) => it.open(),
74 | Self::Singleton(it) => it.open(),
75 }
76 }
77
78 fn up(&mut self) -> bool {
79 match self {
80 | Self::Relation(it) => it.up(),
81 | Self::Singleton(it) => it.up(),
82 }
83 }
84}
85
86impl<IT> IntoIterator for KindIter<IT>
87where
88 IT: TrieIterator,
89{
90 type IntoIter = TrieIteratorWrapper<Self>;
91 type Item = Vec<usize>;
92
93 fn into_iter(self) -> Self::IntoIter { TrieIteratorWrapper::new(self) }
94}
95
96impl<R: TrieIterable> JoinIterable for TrieIterKind<'_, R> {}
97
98impl<R: TrieIterable> TrieIterable for TrieIterKind<'_, R> {
99 fn trie_iter(&self) -> impl TrieIterator + IntoIterator<Item = Vec<usize>> {
100 match self {
101 | Self::Relation(r) => KindIter::Relation(r.trie_iter()),
102 | Self::Singleton(s) => KindIter::Singleton(s.clone()),
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use {
110 super::*,
111 kermit_ds::{Relation, TreeTrie},
112 };
113
114 fn tree_from(tuples: Vec<Vec<usize>>) -> TreeTrie { TreeTrie::from_tuples(2.into(), tuples) }
115
116 #[test]
117 fn kind_relation_delegates_to_inner() {
118 let trie = tree_from(vec![vec![1, 2], vec![3, 4]]);
119 let kind: TrieIterKind<TreeTrie> = TrieIterKind::Relation(&trie);
120 let mut it = kind.trie_iter();
121 assert!(it.open());
122 assert_eq!(it.key(), Some(1));
123 }
124
125 #[test]
126 fn kind_singleton_delegates_to_inner() {
127 let kind: TrieIterKind<TreeTrie> = TrieIterKind::Singleton(SingletonTrieIter::new(7));
128 let mut it = kind.trie_iter();
129 assert!(it.open());
130 assert_eq!(it.key(), Some(7));
131 }
132
133 #[test]
134 fn kind_singleton_seek_behaves_like_bare_singleton() {
135 let kind: TrieIterKind<TreeTrie> = TrieIterKind::Singleton(SingletonTrieIter::new(7));
136 let mut it = kind.trie_iter();
137 it.open();
138 assert!(!it.seek(8));
139 assert!(it.at_end());
140 }
141
142 #[test]
143 fn wrapper_on_kind_iter_yields_tuples() {
144 let trie = tree_from(vec![vec![1, 2]]);
145 let kind: TrieIterKind<TreeTrie> = TrieIterKind::Relation(&trie);
146 let tuples: Vec<Vec<usize>> = kind.trie_iter().into_iter().collect();
147 assert_eq!(tuples, vec![vec![1, 2]]);
148 }
149
150 #[test]
151 fn wrapper_on_kind_singleton_yields_one_tuple() {
152 let kind: TrieIterKind<TreeTrie> = TrieIterKind::Singleton(SingletonTrieIter::new(42));
153 let tuples: Vec<Vec<usize>> = kind.trie_iter().into_iter().collect();
154 assert_eq!(tuples, vec![vec![42]]);
155 }
156}