cynic_parser/type_system/
iter.rs

1use std::{fmt, iter::FusedIterator};
2
3use crate::common::{IdOperations, IdRange, IdRangeIter};
4
5use super::{TypeSystemDocument, TypeSystemId};
6
7/// Iterator for readers in the executable module
8///
9/// T indicates the type that will be yielded by the Iterator
10#[derive(Clone)]
11pub struct Iter<'a, T>
12where
13    T: IdReader,
14{
15    ids: IdRangeIter<T::Id>,
16    document: &'a super::TypeSystemDocument,
17}
18
19impl<'a, T> Iter<'a, T>
20where
21    T: IdReader,
22{
23    pub(crate) fn new(range: IdRange<T::Id>, document: &'a super::TypeSystemDocument) -> Self
24    where
25        T::Id: IdOperations,
26    {
27        Iter {
28            ids: range.into_iter(),
29            document,
30        }
31    }
32
33    pub fn ids(&self) -> IdRange<T::Id> {
34        self.ids.current_range()
35    }
36}
37
38pub trait IdReader {
39    type Id: TypeSystemId;
40    type Reader<'a>;
41
42    fn new(id: Self::Id, document: &'_ TypeSystemDocument) -> Self::Reader<'_>;
43}
44
45impl<'a, T> Iterator for Iter<'a, T>
46where
47    T: IdReader,
48    T::Id: IdOperations,
49{
50    type Item = T::Reader<'a>;
51
52    fn next(&mut self) -> Option<Self::Item> {
53        Some(T::new(self.ids.next()?, self.document))
54    }
55
56    fn size_hint(&self) -> (usize, Option<usize>) {
57        self.ids.size_hint()
58    }
59}
60
61impl<T> ExactSizeIterator for Iter<'_, T>
62where
63    T: IdReader,
64    T::Id: IdOperations,
65{
66}
67
68impl<T> FusedIterator for Iter<'_, T>
69where
70    T: IdReader,
71    T::Id: IdOperations,
72{
73}
74
75impl<T> DoubleEndedIterator for Iter<'_, T>
76where
77    T: IdReader,
78    T::Id: IdOperations,
79{
80    // Required method
81    fn next_back(&mut self) -> Option<Self::Item> {
82        Some(T::new(self.ids.next_back()?, self.document))
83    }
84}
85
86impl<T> fmt::Debug for Iter<'_, T>
87where
88    T: IdReader + Copy,
89    Self: Iterator,
90    <Self as Iterator>::Item: fmt::Debug,
91{
92    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93        f.debug_list().entries(self.clone()).finish()
94    }
95}