arraystring/
drain.rs

1//! Draining iterator for [`ArrayString`]
2//!
3//! [`ArrayString`]: ../struct.ArrayString.html
4
5use crate::{prelude::*, utils::IntoLossy};
6use core::fmt::{self, Debug, Formatter};
7use core::{cmp::Ordering, hash::Hash, hash::Hasher, iter::FusedIterator};
8
9/// A draining iterator for [`ArrayString`].
10///
11/// Created through [`drain`]
12///
13/// [`ArrayString`]: ../struct.ArrayString.html
14/// [`drain`]: ../struct.ArrayString.html#method.drain
15#[derive(Clone, Default)]
16pub struct Drain<S: Capacity>(pub(crate) ArrayString<S>, pub(crate) u8);
17
18impl<SIZE> Debug for Drain<SIZE>
19where
20    SIZE: Capacity,
21{
22    #[inline]
23    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
24        f.debug_tuple("Drain")
25            .field(&self.0)
26            .field(&self.1)
27            .finish()
28    }
29}
30
31impl<SIZE> PartialEq for Drain<SIZE>
32where
33    SIZE: Capacity,
34{
35    #[inline]
36    fn eq(&self, other: &Self) -> bool {
37        self.as_str().eq(other.as_str())
38    }
39}
40impl<SIZE: Capacity> Eq for Drain<SIZE> {}
41
42impl<SIZE> Ord for Drain<SIZE>
43where
44    SIZE: Capacity,
45{
46    #[inline]
47    fn cmp(&self, other: &Self) -> Ordering {
48        self.as_str().cmp(other.as_str())
49    }
50}
51
52impl<SIZE> PartialOrd for Drain<SIZE>
53where
54    SIZE: Capacity,
55{
56    #[inline]
57    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
58        Some(self.cmp(other))
59    }
60}
61
62impl<SIZE> Hash for Drain<SIZE>
63where
64    SIZE: Capacity,
65{
66    #[inline]
67    fn hash<H: Hasher>(&self, hasher: &mut H) {
68        self.as_str().hash(hasher)
69    }
70}
71
72impl<SIZE: Capacity + Copy> Copy for Drain<SIZE> where SIZE::Array: Copy {}
73
74impl<S: Capacity> Drain<S> {
75    /// Extracts string slice containing the remaining characters of `Drain`.
76    #[inline]
77    pub fn as_str(&self) -> &str {
78        unsafe { self.0.as_str().get_unchecked(self.1.into()..) }
79    }
80}
81
82impl<S: Capacity> Iterator for Drain<S> {
83    type Item = char;
84
85    #[inline]
86    fn next(&mut self) -> Option<Self::Item> {
87        self.0
88            .as_str()
89            .get(self.1.into()..)
90            .and_then(|s| s.chars().next())
91            .map(|c| {
92                self.1 = self.1.saturating_add(c.len_utf8().into_lossy());
93                c
94            })
95    }
96}
97
98impl<S: Capacity> DoubleEndedIterator for Drain<S> {
99    #[inline]
100    fn next_back(&mut self) -> Option<Self::Item> {
101        self.0.pop()
102    }
103}
104
105impl<S: Capacity> FusedIterator for Drain<S> {}