gear_common/storage/primitives/iterable.rs
1// This file is part of Gear.
2
3// Copyright (C) 2022-2025 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Module for map's iterator primitives.
20//!
21//! Map's iterators primitives declares the ability
22//! to iter through defined generic `Item` over the map
23//! with specified (associated) types of iterators
24//! for drain or just iter elements.
25//!
26//! `DrainIter` used for element's removal
27//! on each iteration, while `Iter` used for
28//! just checking them.
29
30use super::TransposeCallback;
31use core::marker::PhantomData;
32
33/// Represents iterable logic for double key maps
34/// (Key1 -> Key2 -> Value).
35///
36/// Returns the iterators over specified (associated)
37/// type of the first key's items.
38pub trait IterableByKeyMap<Item> {
39 /// Map's first key type.
40 type Key;
41 /// Removal iterator type.
42 type DrainIter: Iterator<Item = Item>;
43 /// Getting iterator type.
44 type Iter: Iterator<Item = Item>;
45
46 /// Creates the removal iterator over double map Items.
47 fn drain_key(key: Self::Key) -> Self::DrainIter;
48 /// Creates the getting iterator over double map Items.
49 fn iter_key(key: Self::Key) -> Self::Iter;
50}
51
52/// Represents iterable logic for single key maps
53/// (Key -> Value).
54pub trait IterableMap<Item> {
55 /// Removal iterator type.
56 type DrainIter: Iterator<Item = Item>;
57 /// Getting iterator type.
58 type Iter: Iterator<Item = Item>;
59
60 /// Creates the removal iterator over map Items.
61 fn drain() -> Self::DrainIter;
62 /// Creates the getting iterator over map Items.
63 fn iter() -> Self::Iter;
64}
65
66/// Represents iterable over second keys logic for double key maps
67/// (Key1 -> Key2 -> Value).
68///
69/// Returns the iterators over specified (associated)
70/// type of the second map keys by given first key.
71pub trait KeyIterableByKeyMap {
72 /// Map's first key type.
73 type Key1;
74 /// Map's second key type.
75 type Key2;
76 /// Removal iterator type.
77 type DrainIter: Iterator<Item = Self::Key2>;
78 /// Getting iterator type.
79 type Iter: Iterator<Item = Self::Key2>;
80
81 /// Creates the removal iterator over double map Items.
82 fn drain_prefix_keys(key: Self::Key1) -> Self::DrainIter;
83 /// Creates the getting iterator over double map Items.
84 fn iter_prefix_keys(key: Self::Key1) -> Self::Iter;
85}
86
87/// Transpose callback for getting first element of tuple.
88pub struct GetFirstPos;
89
90// `TransposeCallback` implementation for tuple with two elements.
91impl<K, V> TransposeCallback<(K, V), K> for GetFirstPos {
92 fn call(arg: (K, V)) -> K {
93 arg.0
94 }
95}
96
97// `TransposeCallback` implementation for tuple with three elements.
98impl<K1, K2, V> TransposeCallback<(K1, K2, V), K1> for GetFirstPos {
99 fn call(arg: (K1, K2, V)) -> K1 {
100 arg.0
101 }
102}
103
104/// Transpose callback for getting second element of tuple.
105pub struct GetSecondPos;
106
107// `TransposeCallback` implementation for tuple with two elements.
108impl<K, V> TransposeCallback<(K, V), V> for GetSecondPos {
109 fn call(arg: (K, V)) -> V {
110 arg.1
111 }
112}
113
114// `TransposeCallback` implementation for tuple with three elements.
115impl<K1, K2, V> TransposeCallback<(K1, K2, V), K2> for GetSecondPos {
116 fn call(arg: (K1, K2, V)) -> K2 {
117 arg.1
118 }
119}
120
121/// Transpose callback for getting third element of tuple.
122pub struct GetThirdPos;
123
124// `TransposeCallback` implementation for tuple with three elements.
125impl<K1, K2, V> TransposeCallback<(K1, K2, V), V> for GetThirdPos {
126 fn call(arg: (K1, K2, V)) -> V {
127 arg.2
128 }
129}
130
131/// Represents wrapper for any iterator with ability
132/// to transpose `.next()` result.
133pub struct IteratorWrap<I, Item = <I as Iterator>::Item, TC = ()>(I, PhantomData<(Item, TC)>)
134where
135 I: Iterator,
136 TC: TransposeCallback<I::Item, Item>;
137
138// Implementation of `From` for any iterator.
139impl<I, Item, TC> From<I> for IteratorWrap<I, Item, TC>
140where
141 I: Iterator,
142 TC: TransposeCallback<I::Item, Item>,
143{
144 fn from(iterator: I) -> Self {
145 Self(iterator, PhantomData)
146 }
147}
148
149// Implementation of `Iterator` itself for the wrapper
150// based on inner iterator and transpose callback.
151impl<I, Item, TC> Iterator for IteratorWrap<I, Item, TC>
152where
153 I: Iterator,
154 TC: TransposeCallback<I::Item, Item>,
155{
156 type Item = Item;
157
158 fn next(&mut self) -> Option<Self::Item> {
159 self.0.next().map(TC::call)
160 }
161}