1use crate::{prelude::*, utils::IntoLossy};
6use core::fmt::{self, Debug, Formatter};
7use core::{cmp::Ordering, hash::Hash, hash::Hasher, iter::FusedIterator};
8
9#[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 #[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> {}