kutil_std/foster/
bytestr_vector.rs

1use super::{
2    super::{borrow::*, iter::*},
3    foster::*,
4    has_length::*,
5    iterator::*,
6};
7
8use {
9    bytestr::*,
10    std::{cmp::*, hash::*, slice::*},
11};
12
13/// [Foster] for [Vec]\<[ByteStr]\>.
14///
15/// Supports [IntoOwned], [HasLength], [Eq]/[PartialEq], [Ord]/[PartialOrd], [Hash], and
16/// [IntoIterator].
17pub type FosterByteStrVector = Foster<Vec<ByteStr>, &'static [&'static str]>;
18
19impl IntoOwned for FosterByteStrVector {
20    fn into_owned(self) -> Self {
21        match self {
22            Self::Owned(_) => self,
23            Self::Fostered(strings) => Self::new_owned(strings.iter().map(|string| (*string).into()).collect()),
24        }
25    }
26}
27
28impl HasLength for FosterByteStrVector {
29    fn len(&self) -> usize {
30        match self {
31            Self::Owned(strings) => strings.len(),
32            Self::Fostered(strings) => strings.len(),
33        }
34    }
35}
36
37impl PartialEq for FosterByteStrVector {
38    fn eq(&self, other: &Self) -> bool {
39        match self {
40            Self::Owned(strings) => match other {
41                Self::Owned(other_strings) => strings.eq(other_strings),
42
43                Self::Fostered(other_strings) => {
44                    if strings.len() == other_strings.len() {
45                        let mut equal = true;
46                        for (index, string) in strings.iter().enumerate() {
47                            if string.ne(other_strings[index]) {
48                                equal = false;
49                                break;
50                            }
51                        }
52                        equal
53                    } else {
54                        false
55                    }
56                }
57            },
58
59            Self::Fostered(strings) => match other {
60                Self::Owned(other_strings) => {
61                    if strings.len() == other_strings.len() {
62                        let mut equal = true;
63                        for (index, string) in strings.iter().enumerate() {
64                            if string.ne(&other_strings[index]) {
65                                equal = false;
66                                break;
67                            }
68                        }
69                        equal
70                    } else {
71                        false
72                    }
73                }
74
75                Self::Fostered(other_strings) => strings.eq(other_strings),
76            },
77        }
78    }
79}
80
81impl Eq for FosterByteStrVector {}
82
83impl Hash for FosterByteStrVector {
84    fn hash<HasherT>(&self, state: &mut HasherT)
85    where
86        HasherT: Hasher,
87    {
88        match self {
89            Self::Owned(strings) => {
90                for string in strings {
91                    state.write(string.as_bytes());
92                }
93            }
94
95            Self::Fostered(strings) => {
96                for string in strings.iter() {
97                    state.write(string.as_bytes());
98                }
99            }
100        }
101    }
102}
103
104impl<'own> IntoIterator for &'own FosterByteStrVector {
105    type Item = &'own str;
106    type IntoIter =
107        FosterIterator<&'own str, &'own ByteStr, &'own &'static str, Iter<'own, ByteStr>, Iter<'own, &'static str>>;
108
109    fn into_iter(self) -> Self::IntoIter {
110        match self {
111            Foster::Owned(strings) => Foster::new_owned(ConvertingIterator::new(strings.iter(), |string| &string)),
112            Foster::Fostered(strings) => Foster::new_static(ConvertingIterator::new(strings.iter(), |string| string)),
113        }
114    }
115}
116
117/// Delegates traits to a [FosterByteStrVector] newtype.
118///
119/// Example:
120///
121/// ```
122/// #[derive(Clone, Debug)]
123/// pub struct MyType(FosterByteStrVector);
124///
125/// delegate_newtype_of_foster_bytestr_vector!(MyType);
126/// ```
127///
128#[macro_export]
129macro_rules! delegate_newtype_of_foster_bytestr_vector {
130    ( $type:ty ) => {
131        impl $type {
132            /// Constructor.
133            pub fn new_owned(strings: ::std::vec::Vec<::bytestr::ByteStr>) -> Self {
134                Self(::kutil_std::foster::Foster::new_owned(strings))
135            }
136
137            /// Constructor.
138            pub const fn new_static(strings: &'static [&'static str]) -> Self {
139                Self(::kutil_std::foster::Foster::new_static(strings))
140            }
141        }
142
143        impl ::kutil_std::borrow::IntoOwned for $type {
144            fn into_owned(self) -> Self {
145                match self.0 {
146                    ::kutil_std::foster::Foster::Owned(_) => self,
147                    ::kutil_std::foster::Foster::Fostered(_) => Self(self.0.into_owned()),
148                }
149            }
150        }
151
152        impl ::kutil_std::foster::HasLength for $type {
153            fn len(&self) -> usize {
154                self.0.len()
155            }
156        }
157
158        impl From<::std::vec::Vec<::bytestr::ByteStr>> for $type {
159            fn from(strings: Vec<::bytestr::ByteStr>) -> Self {
160                strings.into()
161            }
162        }
163
164        impl ::std::cmp::PartialEq for $type {
165            fn eq(&self, other: &Self) -> bool {
166                self.0.eq(&other.0)
167            }
168        }
169
170        impl ::std::cmp::Eq for $type {}
171
172        impl ::std::hash::Hash for $type {
173            fn hash<HasherT>(&self, state: &mut HasherT)
174            where
175                HasherT: ::std::hash::Hasher,
176            {
177                self.0.hash(state)
178            }
179        }
180
181        impl<'own> ::std::iter::IntoIterator for &'own $type {
182            type Item = &'own str;
183            type IntoIter = ::kutil_std::foster::FosterIterator<
184                &'own str,
185                &'own ::bytestr::ByteStr,
186                &'own &'static str,
187                ::std::slice::Iter<'own, ::bytestr::ByteStr>,
188                ::std::slice::Iter<'own, &'static str>,
189            >;
190
191            fn into_iter(self) -> Self::IntoIter {
192                self.0.into_iter()
193            }
194        }
195    };
196}