orx_concurrent_iter/exact_size_concurrent_iter.rs
1use crate::{IntoConcurrentIter, chain::ChainKnownLenI, concurrent_iter::ConcurrentIter};
2
3/// A concurrent iterator which has a certain information of the number of
4/// remaining elements.
5///
6/// It can be considered as the *concurrent counterpart* of the [`ExactSizeIterator`].
7///
8/// # Examples
9///
10/// ```
11/// use orx_concurrent_iter::*;
12///
13/// let vec = vec!['x', 'y'];
14///
15/// let con_iter = vec.con_iter();
16/// assert_eq!(con_iter.len(), 2);
17///
18/// assert_eq!(con_iter.next(), Some(&'x'));
19/// assert_eq!(con_iter.len(), 1);
20///
21/// assert_eq!(con_iter.next(), Some(&'y'));
22/// assert_eq!(con_iter.len(), 0);
23/// assert!(con_iter.is_empty());
24///
25/// assert_eq!(con_iter.next(), None);
26/// assert_eq!(con_iter.len(), 0);
27/// assert!(con_iter.is_empty());
28/// ```
29pub trait ExactSizeConcurrentIter: ConcurrentIter {
30 /// Returns the number remaining elements in the concurrent iterator.
31 ///
32 /// # Examples
33 ///
34 /// ```
35 /// use orx_concurrent_iter::*;
36 ///
37 /// let vec = vec!['x', 'y'];
38 ///
39 /// let con_iter = vec.con_iter();
40 /// assert_eq!(con_iter.len(), 2);
41 ///
42 /// assert_eq!(con_iter.next(), Some(&'x'));
43 /// assert_eq!(con_iter.len(), 1);
44 ///
45 /// assert_eq!(con_iter.next(), Some(&'y'));
46 /// assert_eq!(con_iter.len(), 0);
47 /// assert!(con_iter.is_empty());
48 ///
49 /// assert_eq!(con_iter.next(), None);
50 /// assert_eq!(con_iter.len(), 0);
51 /// assert!(con_iter.is_empty());
52 /// ```
53 fn len(&self) -> usize;
54
55 /// Returns true if there are no elements left in the concurrent iterator.
56 /// Returns false otherwise.
57 ///
58 /// # Examples
59 ///
60 /// ```
61 /// use orx_concurrent_iter::*;
62 ///
63 /// let vec = vec!['x', 'y'];
64 ///
65 /// let con_iter = vec.con_iter();
66 /// assert!(!con_iter.is_empty());
67 ///
68 /// assert_eq!(con_iter.next(), Some(&'x'));
69 /// assert!(!con_iter.is_empty());
70 ///
71 /// assert_eq!(con_iter.next(), Some(&'y'));
72 /// assert!(con_iter.is_empty());
73 ///
74 /// assert_eq!(con_iter.next(), None);
75 /// assert!(con_iter.is_empty());
76 /// ```
77 fn is_empty(&self) -> bool {
78 self.len() == 0
79 }
80
81 /// Creates a chain of this and `other` concurrent iterators.
82 ///
83 /// It is preferable to call `chain` over [`chain_inexact`] whenever the first iterator
84 /// implements `ExactSizeConcurrentIter`.
85 ///
86 /// [`chain_inexact`]: crate::ConcurrentIter::chain_inexact
87 ///
88 /// # Examples
89 ///
90 /// ```
91 /// use orx_concurrent_iter::*;
92 ///
93 /// let s1 = "abc".chars(); // exact iter
94 /// let s2 = vec!['d', 'e', 'f'];
95 ///
96 /// let chain = s1.iter_into_con_iter().chain_inexact(s2);
97 ///
98 /// assert_eq!(chain.next(), Some('a'));
99 /// assert_eq!(chain.next(), Some('b'));
100 /// assert_eq!(chain.next(), Some('c'));
101 /// assert_eq!(chain.next(), Some('d'));
102 /// assert_eq!(chain.next(), Some('e'));
103 /// assert_eq!(chain.next(), Some('f'));
104 /// assert_eq!(chain.next(), None);
105 /// ```
106 fn chain<C>(self, other: C) -> ChainKnownLenI<Self, C::IntoIter>
107 where
108 C: IntoConcurrentIter<Item = Self::Item>,
109 Self: Sized,
110 {
111 let len_i = self.len();
112 ChainKnownLenI::new(self, other.into_con_iter(), len_i)
113 }
114}