cynic_parser/executable/
iter.rs1use std::{fmt, iter::FusedIterator};
2
3use crate::common::{IdOperations, IdRange, IdRangeIter};
4
5use super::{ExecutableDocument, ExecutableId};
6
7pub trait IdReader {
8 type Id: ExecutableId;
9 type Reader<'a>;
10
11 fn new(id: Self::Id, document: &'_ ExecutableDocument) -> Self::Reader<'_>;
12}
13
14#[derive(Clone)]
18pub struct Iter<'a, T>
19where
20 T: IdReader,
21{
22 ids: IdRangeIter<T::Id>,
23 document: &'a super::ExecutableDocument,
24}
25
26impl<'a, T> Iter<'a, T>
27where
28 T: IdReader,
29{
30 pub(crate) fn new(range: IdRange<T::Id>, document: &'a super::ExecutableDocument) -> Self
31 where
32 T::Id: IdOperations,
33 {
34 Iter {
35 ids: range.into_iter(),
36 document,
37 }
38 }
39
40 pub fn ids(&self) -> IdRange<T::Id> {
41 self.ids.current_range()
42 }
43
44 pub fn with_ids(&self) -> IdIter<'a, T> {
45 let Iter { ids, document } = self;
46
47 IdIter {
48 ids: ids.clone(),
49 document,
50 }
51 }
52}
53
54impl<'a, T> Iterator for Iter<'a, T>
55where
56 T: IdReader,
57 T::Id: IdOperations,
58{
59 type Item = T::Reader<'a>;
60
61 fn next(&mut self) -> Option<Self::Item> {
62 Some(T::new(self.ids.next()?, self.document))
63 }
64
65 fn size_hint(&self) -> (usize, Option<usize>) {
66 self.ids.size_hint()
67 }
68}
69
70impl<T> ExactSizeIterator for Iter<'_, T>
71where
72 T: IdReader,
73 T::Id: IdOperations,
74{
75}
76
77impl<T> FusedIterator for Iter<'_, T>
78where
79 T: IdReader,
80 T::Id: IdOperations,
81{
82}
83
84impl<T> DoubleEndedIterator for Iter<'_, T>
85where
86 T: IdReader,
87 T::Id: IdOperations,
88{
89 fn next_back(&mut self) -> Option<Self::Item> {
91 Some(T::new(self.ids.next_back()?, self.document))
92 }
93}
94
95impl<T> fmt::Debug for Iter<'_, T>
96where
97 T: IdReader + Copy,
98 Self: Iterator,
99 <Self as Iterator>::Item: fmt::Debug,
100{
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.debug_list().entries(self.clone()).finish()
103 }
104}
105
106#[derive(Clone)]
110pub struct IdIter<'a, T>
111where
112 T: IdReader,
113{
114 ids: IdRangeIter<T::Id>,
115 document: &'a super::ExecutableDocument,
116}
117
118impl<'a, T> Iterator for IdIter<'a, T>
119where
120 T: IdReader,
121 T::Id: IdOperations,
122{
123 type Item = (T::Id, <T::Id as ExecutableId>::Reader<'a>);
124
125 fn next(&mut self) -> Option<Self::Item> {
126 let next = self.ids.next()?;
127
128 Some((next, self.document.read(next)))
129 }
130
131 fn size_hint(&self) -> (usize, Option<usize>) {
132 self.ids.size_hint()
133 }
134}
135
136impl<T> ExactSizeIterator for IdIter<'_, T>
137where
138 T: IdReader,
139 T::Id: IdOperations,
140{
141}
142
143impl<T> FusedIterator for IdIter<'_, T>
144where
145 T: IdReader,
146 T::Id: IdOperations,
147{
148}
149
150impl<T> DoubleEndedIterator for IdIter<'_, T>
151where
152 T: IdReader,
153 T::Id: IdOperations,
154{
155 fn next_back(&mut self) -> Option<Self::Item> {
157 let next = self.ids.next_back()?;
158
159 Some((next, self.document.read(next)))
160 }
161}
162
163impl<T> fmt::Debug for IdIter<'_, T>
164where
165 T: IdReader + Copy,
166 Self: Iterator,
167 <Self as Iterator>::Item: fmt::Debug,
168{
169 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170 f.debug_list().entries(self.clone()).finish()
171 }
172}