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{}