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}