1#![allow(clippy::type_complexity)]
15
16use std::borrow::Borrow;
17use std::iter::Iterator;
18
19use webgraph::prelude::*;
20
21use crate::graph::{NodeId, SwhGraphWithProperties};
22use crate::labels::{EdgeLabel, UntypedEdgeLabel};
23
24pub trait IntoFlattenedLabeledArcsIterator<Label> {
25 type Flattened: IntoIterator<Item = (NodeId, Label)>;
26
27 fn flatten_labels(self) -> Self::Flattened;
30}
31
32pub struct LabeledSuccessorIterator<Successors: Iterator>
33where
34 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
35{
36 pub(crate) successors: Successors,
37}
38
39impl<Successors: Iterator> LabeledSuccessorIterator<Successors>
40where
41 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
42{
43 pub fn new(successors: Successors) -> Self {
44 LabeledSuccessorIterator { successors }
45 }
46}
47
48impl<Successors: Iterator> Iterator for LabeledSuccessorIterator<Successors>
49where
50 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
51{
52 type Item = (
53 NodeId,
54 LabeledArcIterator<
55 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::IntoIter,
56 >,
57 );
58
59 fn next(&mut self) -> Option<Self::Item> {
60 self.successors.next().map(|pair| {
61 let (successor, arc_labels) = pair.into_pair();
62 (
63 successor,
64 LabeledArcIterator {
65 arc_label_ids: arc_labels.into_iter(),
66 },
67 )
68 })
69 }
70}
71
72impl<Successors: Iterator> IntoFlattenedLabeledArcsIterator<UntypedEdgeLabel>
73 for LabeledSuccessorIterator<Successors>
74where
75 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator<Item: Borrow<u64>>>,
76{
77 type Flattened = FlattenedSuccessorsIterator<Self>;
78
79 fn flatten_labels(self) -> Self::Flattened {
80 FlattenedSuccessorsIterator::new(self)
81 }
82}
83
84pub struct FlattenedSuccessorsIterator<Successors: Iterator>
85where
86 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator>,
87{
88 current_node_and_labels: Option<(
89 NodeId,
90 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::IntoIter,
91 )>,
92 iter: Successors,
93}
94
95impl<Successors: Iterator> FlattenedSuccessorsIterator<Successors>
96where
97 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator>,
98{
99 pub fn new(successors: Successors) -> Self {
100 Self {
101 current_node_and_labels: None,
102 iter: successors,
103 }
104 }
105}
106
107impl<Successors: Iterator> Iterator for FlattenedSuccessorsIterator<Successors>
108where
109 <Successors as Iterator>::Item: Pair<Left = usize, Right: IntoIterator>,
110{
111 type Item = (
112 NodeId,
113 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::Item,
114 );
115
116 fn next(&mut self) -> Option<Self::Item> {
117 if self.current_node_and_labels.is_none() {
118 self.current_node_and_labels = self
120 .iter
121 .next()
122 .map(Pair::into_pair)
123 .map(|(succ, labels)| (succ, labels.into_iter()))
124 }
125 let Some((current_node, ref mut current_labels)) = self.current_node_and_labels else {
126 return None;
128 };
129 match current_labels.next() {
130 Some(label) => Some((current_node, label)),
131 None => {
132 self.current_node_and_labels = None;
134 self.next()
135 }
136 }
137 }
138}
139
140pub struct LabeledArcIterator<T: Iterator>
141where
142 <T as Iterator>::Item: Borrow<u64>,
143{
144 arc_label_ids: T,
145}
146
147impl<T: Iterator> Iterator for LabeledArcIterator<T>
148where
149 <T as Iterator>::Item: Borrow<u64>,
150{
151 type Item = UntypedEdgeLabel;
152
153 fn next(&mut self) -> Option<Self::Item> {
154 self.arc_label_ids
155 .next()
156 .map(|label| UntypedEdgeLabel::from(*label.borrow()))
157 }
158}
159
160pub struct LabelTypingSuccessorIterator<'a, G, Successors: Iterator>
161where
162 <Successors as Iterator>::Item:
163 Pair<Left = usize, Right: IntoIterator<Item = UntypedEdgeLabel>>,
164 G: SwhGraphWithProperties,
165 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
166{
167 pub(crate) graph: &'a G,
168 pub(crate) is_transposed: bool,
169 pub(crate) successors: Successors,
170 pub(crate) src: NodeId,
171}
172
173impl<'a, G, Successors: Iterator> Iterator for LabelTypingSuccessorIterator<'a, G, Successors>
174where
175 <Successors as Iterator>::Item:
176 Pair<Left = usize, Right: IntoIterator<Item = UntypedEdgeLabel>>,
177 G: SwhGraphWithProperties,
178 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
179{
180 type Item = (
181 NodeId,
182 LabelTypingArcIterator<
183 'a,
184 G,
185 <<<Successors as Iterator>::Item as Pair>::Right as IntoIterator>::IntoIter,
186 >,
187 );
188
189 fn next(&mut self) -> Option<Self::Item> {
190 self.successors.next().map(|pair| {
191 let mut src = self.src;
192 let (mut dst, labels) = pair.into_pair();
193 let succ = dst;
194 if self.is_transposed {
195 (src, dst) = (dst, src)
196 }
197 (
198 succ,
199 LabelTypingArcIterator {
200 graph: self.graph,
201 labels: labels.into_iter(),
202 src,
203 dst,
204 },
205 )
206 })
207 }
208}
209
210impl<G, Successors: Iterator> IntoFlattenedLabeledArcsIterator<EdgeLabel>
211 for LabelTypingSuccessorIterator<'_, G, Successors>
212where
213 <Successors as Iterator>::Item:
214 Pair<Left = usize, Right: IntoIterator<Item = UntypedEdgeLabel>>,
215 G: SwhGraphWithProperties,
216 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
217{
218 type Flattened = FlattenedSuccessorsIterator<Self>;
219
220 fn flatten_labels(self) -> Self::Flattened {
221 FlattenedSuccessorsIterator::new(self)
222 }
223}
224
225pub struct LabelTypingArcIterator<'a, G, Labels: Iterator<Item = UntypedEdgeLabel>>
226where
227 G: SwhGraphWithProperties,
228 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
229{
230 graph: &'a G,
231 labels: Labels,
232 src: NodeId,
233 dst: NodeId,
234}
235
236impl<G, Labels: Iterator<Item = UntypedEdgeLabel>> Iterator
237 for LabelTypingArcIterator<'_, G, Labels>
238where
239 G: SwhGraphWithProperties,
240 <G as SwhGraphWithProperties>::Maps: crate::properties::Maps,
241{
242 type Item = EdgeLabel;
243
244 fn next(&mut self) -> Option<Self::Item> {
245 let props = self.graph.properties();
246 self.labels.next().map(move |label| {
247 label
248 .for_edge_type(
249 props.node_type(self.src),
250 props.node_type(self.dst),
251 self.graph.is_transposed(),
252 )
253 .unwrap_or_else(|e| {
254 panic!(
255 "Unexpected edge from {} ({}) to {} ({}): {}",
256 props.swhid(self.src),
257 self.src,
258 props.swhid(self.dst),
259 self.dst,
260 e
261 )
262 })
263 })
264 }
265}
266
267pub struct DelabelingIterator<Successors: Iterator>
269where
270 <Successors as Iterator>::Item: Pair<Left = usize>,
271{
272 pub(crate) successors: Successors,
273}
274impl<Successors: Iterator> Iterator for DelabelingIterator<Successors>
275where
276 <Successors as Iterator>::Item: Pair<Left = usize>,
277{
278 type Item = NodeId;
279
280 fn next(&mut self) -> Option<Self::Item> {
281 self.successors.next().map(|pair| {
282 let (successor, _arc_labels) = pair.into_pair();
283 successor
284 })
285 }
286}