gear_common/storage/primitives/iterable.rs
1// Copyright (C) Gear Technologies Inc.
2// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
3
4//! Module for map's iterator primitives.
5//!
6//! Map's iterators primitives declares the ability
7//! to iter through defined generic `Item` over the map
8//! with specified (associated) types of iterators
9//! for drain or just iter elements.
10//!
11//! `DrainIter` used for element's removal
12//! on each iteration, while `Iter` used for
13//! just checking them.
14
15use super::TransposeCallback;
16use core::marker::PhantomData;
17
18/// Represents iterable logic for double key maps
19/// (Key1 -> Key2 -> Value).
20///
21/// Returns the iterators over specified (associated)
22/// type of the first key's items.
23pub trait IterableByKeyMap<Item> {
24 /// Map's first key type.
25 type Key;
26 /// Removal iterator type.
27 type DrainIter: Iterator<Item = Item>;
28 /// Getting iterator type.
29 type Iter: Iterator<Item = Item>;
30
31 /// Creates the removal iterator over double map Items.
32 fn drain_key(key: Self::Key) -> Self::DrainIter;
33 /// Creates the getting iterator over double map Items.
34 fn iter_key(key: Self::Key) -> Self::Iter;
35}
36
37/// Represents iterable logic for single key maps
38/// (Key -> Value).
39pub trait IterableMap<Item> {
40 /// Removal iterator type.
41 type DrainIter: Iterator<Item = Item>;
42 /// Getting iterator type.
43 type Iter: Iterator<Item = Item>;
44
45 /// Creates the removal iterator over map Items.
46 fn drain() -> Self::DrainIter;
47 /// Creates the getting iterator over map Items.
48 fn iter() -> Self::Iter;
49}
50
51/// Represents iterable over second keys logic for double key maps
52/// (Key1 -> Key2 -> Value).
53///
54/// Returns the iterators over specified (associated)
55/// type of the second map keys by given first key.
56pub trait KeyIterableByKeyMap {
57 /// Map's first key type.
58 type Key1;
59 /// Map's second key type.
60 type Key2;
61 /// Removal iterator type.
62 type DrainIter: Iterator<Item = Self::Key2>;
63 /// Getting iterator type.
64 type Iter: Iterator<Item = Self::Key2>;
65
66 /// Creates the removal iterator over double map Items.
67 fn drain_prefix_keys(key: Self::Key1) -> Self::DrainIter;
68 /// Creates the getting iterator over double map Items.
69 fn iter_prefix_keys(key: Self::Key1) -> Self::Iter;
70}
71
72/// Transpose callback for getting first element of tuple.
73pub struct GetFirstPos;
74
75// `TransposeCallback` implementation for tuple with two elements.
76impl<K, V> TransposeCallback<(K, V), K> for GetFirstPos {
77 fn call(arg: (K, V)) -> K {
78 arg.0
79 }
80}
81
82// `TransposeCallback` implementation for tuple with three elements.
83impl<K1, K2, V> TransposeCallback<(K1, K2, V), K1> for GetFirstPos {
84 fn call(arg: (K1, K2, V)) -> K1 {
85 arg.0
86 }
87}
88
89/// Transpose callback for getting second element of tuple.
90pub struct GetSecondPos;
91
92// `TransposeCallback` implementation for tuple with two elements.
93impl<K, V> TransposeCallback<(K, V), V> for GetSecondPos {
94 fn call(arg: (K, V)) -> V {
95 arg.1
96 }
97}
98
99// `TransposeCallback` implementation for tuple with three elements.
100impl<K1, K2, V> TransposeCallback<(K1, K2, V), K2> for GetSecondPos {
101 fn call(arg: (K1, K2, V)) -> K2 {
102 arg.1
103 }
104}
105
106/// Transpose callback for getting third element of tuple.
107pub struct GetThirdPos;
108
109// `TransposeCallback` implementation for tuple with three elements.
110impl<K1, K2, V> TransposeCallback<(K1, K2, V), V> for GetThirdPos {
111 fn call(arg: (K1, K2, V)) -> V {
112 arg.2
113 }
114}
115
116/// Represents wrapper for any iterator with ability
117/// to transpose `.next()` result.
118pub struct IteratorWrap<I, Item = <I as Iterator>::Item, TC = ()>(I, PhantomData<(Item, TC)>)
119where
120 I: Iterator,
121 TC: TransposeCallback<I::Item, Item>;
122
123// Implementation of `From` for any iterator.
124impl<I, Item, TC> From<I> for IteratorWrap<I, Item, TC>
125where
126 I: Iterator,
127 TC: TransposeCallback<I::Item, Item>,
128{
129 fn from(iterator: I) -> Self {
130 Self(iterator, PhantomData)
131 }
132}
133
134// Implementation of `Iterator` itself for the wrapper
135// based on inner iterator and transpose callback.
136impl<I, Item, TC> Iterator for IteratorWrap<I, Item, TC>
137where
138 I: Iterator,
139 TC: TransposeCallback<I::Item, Item>,
140{
141 type Item = Item;
142
143 fn next(&mut self) -> Option<Self::Item> {
144 self.0.next().map(TC::call)
145 }
146}