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}