kutil_std/foster/
byte_string_vector.rs1use super::{
2 super::{borrow::*, iter::*},
3 foster::*,
4 has_length::*,
5 iterator::*,
6};
7
8use {
9 bytestring::*,
10 std::{cmp::*, hash::*, slice::*},
11};
12
13pub type FosterByteStringVector = Foster<Vec<ByteString>, &'static [&'static str]>;
18
19impl IntoOwned for FosterByteStringVector {
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 FosterByteStringVector {
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 FosterByteStringVector {
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 let other_string: &str = &other_strings[index];
65 if (*string).ne(other_string) {
66 equal = false;
67 break;
68 }
69 }
70 equal
71 } else {
72 false
73 }
74 }
75
76 Self::Fostered(other_strings) => strings.eq(other_strings),
77 },
78 }
79 }
80}
81
82impl Eq for FosterByteStringVector {}
83
84impl PartialOrd for FosterByteStringVector {
85 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
86 match self {
89 Self::Owned(strings) => match other {
90 Self::Owned(other_strings) => strings.partial_cmp(other_strings),
91
92 Self::Fostered(other_strings) => {
93 let strings_length = strings.len();
94 let other_strings_length = other_strings.len();
95 let length = min(strings_length, other_strings_length);
96
97 let strings_bounded = &strings[..length];
99 let other_strings_bounded = &other_strings[..length];
100
101 for index in 0..length {
102 match (*strings_bounded[index]).partial_cmp(other_strings_bounded[index]) {
103 Some(Ordering::Equal) => (),
104 not_equal => return not_equal,
105 }
106 }
107
108 strings_length.partial_cmp(&other_strings_length)
109 }
110 },
111
112 Self::Fostered(strings) => match other {
113 Self::Owned(other_strings) => {
114 let strings_length = strings.len();
115 let other_strings_length = other_strings.len();
116 let length = min(strings_length, other_strings_length);
117
118 let strings_bounded = &strings[..length];
120 let other_strings_bounded = &other_strings[..length];
121
122 for index in 0..length {
123 let other_string_bounded: &str = &other_strings_bounded[index];
124 match strings_bounded[index].partial_cmp(other_string_bounded) {
125 Some(Ordering::Equal) => (),
126 not_equal => return not_equal,
127 }
128 }
129
130 strings_length.partial_cmp(&other_strings_length)
131 }
132
133 Self::Fostered(other_strings) => strings.partial_cmp(other_strings),
134 },
135 }
136 }
137}
138
139impl Ord for FosterByteStringVector {
140 fn cmp(&self, other: &Self) -> Ordering {
141 match self {
144 Self::Owned(strings) => match other {
145 Self::Owned(other_strings) => strings.cmp(other_strings),
146
147 Self::Fostered(other_strings) => {
148 let strings_length = strings.len();
149 let other_strings_length = other_strings.len();
150 let length = min(strings_length, other_strings_length);
151
152 let strings_bounded = &strings[..length];
154 let other_strings_bounded = &other_strings[..length];
155
156 for index in 0..length {
157 match (*strings_bounded[index]).cmp(other_strings_bounded[index]) {
158 Ordering::Equal => (),
159 not_equal => return not_equal,
160 }
161 }
162
163 strings_length.cmp(&other_strings_length)
164 }
165 },
166
167 Self::Fostered(strings) => match other {
168 Self::Owned(other_strings) => {
169 let strings_length = strings.len();
170 let other_strings_length = other_strings.len();
171 let length = min(strings_length, other_strings_length);
172
173 let strings_bounded = &strings[..length];
175 let other_strings_bounded = &other_strings[..length];
176
177 for index in 0..length {
178 let other_string_bounded: &str = &other_strings_bounded[index];
179 match strings_bounded[index].cmp(other_string_bounded) {
180 Ordering::Equal => (),
181 not_equal => return not_equal,
182 }
183 }
184
185 strings_length.cmp(&other_strings_length)
186 }
187
188 Self::Fostered(other_strings) => strings.cmp(other_strings),
189 },
190 }
191 }
192}
193
194impl Hash for FosterByteStringVector {
195 fn hash<HasherT>(&self, state: &mut HasherT)
196 where
197 HasherT: Hasher,
198 {
199 match self {
200 Self::Owned(strings) => {
201 for string in strings {
202 state.write(string.as_bytes());
203 }
204 }
205
206 Self::Fostered(strings) => {
207 for string in strings.iter() {
208 state.write(string.as_bytes());
209 }
210 }
211 }
212 }
213}
214
215impl<'own> IntoIterator for &'own FosterByteStringVector {
216 type Item = &'own str;
217 type IntoIter = FosterIterator<
218 &'own str,
219 &'own ByteString,
220 &'own &'static str,
221 Iter<'own, ByteString>,
222 Iter<'own, &'static str>,
223 >;
224
225 fn into_iter(self) -> Self::IntoIter {
226 match self {
227 Foster::Owned(strings) => Foster::new_owned(ConvertingIterator::new(strings.iter(), |string| &string)),
228 Foster::Fostered(strings) => Foster::new_fostered(ConvertingIterator::new(strings.iter(), |string| string)),
229 }
230 }
231}
232
233#[macro_export]
245macro_rules! delegate_newtype_of_foster_byte_string_vector {
246 ( $type:ty ) => {
247 impl $type {
248 pub fn new_owned(strings: ::std::vec::Vec<::bytestring::ByteString>) -> Self {
250 Self(::kutil_std::foster::Foster::new_owned(strings))
251 }
252
253 pub const fn new_fostered(strings: &'static [&'static str]) -> Self {
255 Self(::kutil_std::foster::Foster::new_fostered(strings))
256 }
257 }
258
259 impl ::kutil_std::borrow::IntoOwned for $type {
260 fn into_owned(self) -> Self {
261 match self.0 {
262 ::kutil_std::foster::Foster::Owned(_) => self,
263 ::kutil_std::foster::Foster::Fostered(_) => Self(self.0.into_owned()),
264 }
265 }
266 }
267
268 impl ::kutil_std::foster::HasLength for $type {
269 fn len(&self) -> usize {
270 self.0.len()
271 }
272 }
273
274 impl ::std::convert::From<::std::vec::Vec<::bytestring::ByteString>> for $type {
275 fn from(strings: Vec<::bytestring::ByteString>) -> Self {
276 strings.into()
277 }
278 }
279
280 impl ::std::cmp::PartialEq for $type {
281 fn eq(&self, other: &Self) -> bool {
282 self.0.eq(&other.0)
283 }
284 }
285
286 impl ::std::cmp::Eq for $type {}
287
288 impl ::std::cmp::PartialOrd for $type {
289 fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
290 self.0.partial_cmp(&other.0)
291 }
292 }
293
294 impl ::std::cmp::Ord for $type {
295 fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
296 self.0.cmp(&other.0)
297 }
298 }
299
300 impl ::std::hash::Hash for $type {
301 fn hash<HasherT>(&self, state: &mut HasherT)
302 where
303 HasherT: ::std::hash::Hasher,
304 {
305 self.0.hash(state)
306 }
307 }
308
309 impl<'own> ::std::iter::IntoIterator for &'own $type {
310 type Item = &'own str;
311 type IntoIter = ::kutil_std::foster::FosterIterator<
312 &'own str,
313 &'own ::bytestring::ByteString,
314 &'own &'static str,
315 ::std::slice::Iter<'own, ::bytestring::ByteString>,
316 ::std::slice::Iter<'own, &'static str>,
317 >;
318
319 fn into_iter(self) -> Self::IntoIter {
320 self.0.into_iter()
321 }
322 }
323 };
324}