iter_trait/
base.rs

1//! Base iterator traits.
2
3cfg_if! {
4    if #[cfg(feature = "std")] {
5        use std::iter::FromIterator;
6    } else {
7        use core::iter::FromIterator;
8    }
9}
10
11use refs::{Ref, RefMut};
12
13/// A trait for iterable collections which contain data of a given type.
14///
15/// In most cases, you shouldn't implement this trait directly; instead, you should implement
16/// `IntoIterator`, which will in turn implement this trait.
17///
18/// The only exception is dynamically-sized types, which cannot implement `IntoIterator`. Instead,
19/// you should implement this trait to indicate what type of data is inside the collection.
20pub trait HasData {
21    /// The type of the data inside this collection.
22    type Item;
23}
24impl<T: IntoIterator> HasData for T {
25    type Item = <T as IntoIterator>::Item;
26}
27
28/// A trait for collections which can be iterated by reference.
29///
30/// In most cases, you shouldn't implement this trait directly; instead, you should implement
31/// `IntoIterator` for a reference of this type, which will in turn implement this trait.
32pub trait Iter<'a>: 'a + HasData {
33    /// Type of the references to the data in the collection.
34    ///
35    /// Although this might just be `&'a Item`, it can also be more complicated. For example, an
36    /// iterator with `Item = (usize, T)` might use `(usize, &'a T)` for this instead.
37    ///
38    /// For more information, see the `Ref` trait.
39    type ItemRef: Ref<'a, Self::Item>;
40
41    /// Type of the iterator over references.
42    type IterRef: Iterator<Item = Self::ItemRef>;
43
44    /// Constructs an iterator over references to the data in this collection.
45    fn iter(&'a self) -> Self::IterRef;
46}
47impl<'a, T: 'a + HasData> Iter<'a> for T
48where
49    &'a T: IntoIterator,
50    <&'a T as IntoIterator>::Item: Ref<'a, T::Item>,
51{
52    type ItemRef = <&'a Self as IntoIterator>::Item;
53    type IterRef = <&'a Self as IntoIterator>::IntoIter;
54    fn iter(&'a self) -> Self::IterRef {
55        self.into_iter()
56    }
57}
58
59/// A trait for collections which can be iterated by mutable reference.
60///
61/// In most cases, you shouldn't implement this trait directly; instead, you should implement
62/// `IntoIterator` for a mutable reference of this type, which will in turn implement this trait.
63pub trait IterMut<'a>: Iter<'a> {
64    /// Type of the mutable references to the data in the collection.
65    ///
66    /// Although this might just be `&'a Item`, it can also be more complicated. For example, an
67    /// iterator with `Item = (usize, T)` might use `(usize, &'a mut T)` for this instead.
68    ///
69    /// For more information, see the `RefMut` trait.
70    type ItemMut: RefMut<'a, Self::Item>;
71
72    /// Type of the iterator over mutable references.
73    type IterMut: Iterator<Item = Self::ItemMut>;
74
75    /// Constructs an iterator over mutable references to the data in this collection.
76    fn iter_mut(&'a mut self) -> Self::IterMut;
77}
78impl<'a, T: 'a + Iter<'a>> IterMut<'a> for T
79where
80    &'a mut T: IntoIterator,
81    <&'a mut T as IntoIterator>::Item: RefMut<'a, T::Item>,
82{
83    type ItemMut = <&'a mut Self as IntoIterator>::Item;
84    type IterMut = <&'a mut Self as IntoIterator>::IntoIter;
85    fn iter_mut(&'a mut self) -> Self::IterMut {
86        self.into_iter()
87    }
88}
89
90/// A trait for collections which can be converted to and from iterators over data.
91pub trait IterOwned
92    : HasData
93    + IntoIterator<Item = <Self as HasData>::Item>
94    + FromIterator<<Self as HasData>::Item>
95    + Extend<<Self as HasData>::Item>
96{}
97impl<T> IterOwned for T
98where
99    T: HasData,
100    T: IntoIterator<Item = <T as HasData>::Item>,
101    T: FromIterator<<T as HasData>::Item>,
102    T: Extend<<T as HasData>::Item>,
103{}