kutil_std/foster/
string_vector.rs1use super::{
2 super::{borrow::*, iter::*},
3 foster::*,
4 has_length::*,
5 iterator::*,
6};
7
8use std::{cmp::*, hash::*, slice::*};
9
10pub type FosterStringVector = Foster<Vec<String>, &'static [&'static str]>;
15
16impl IntoOwned for FosterStringVector {
17 fn into_owned(self) -> Self {
18 match self {
19 Self::Owned(_) => self,
20 Self::Fostered(strings) => Self::new_owned(strings.iter().map(|string| (*string).into()).collect()),
21 }
22 }
23}
24
25impl HasLength for FosterStringVector {
26 fn len(&self) -> usize {
27 match self {
28 Self::Owned(strings) => strings.len(),
29 Self::Fostered(strings) => strings.len(),
30 }
31 }
32}
33
34impl PartialEq for FosterStringVector {
35 fn eq(&self, other: &Self) -> bool {
36 match self {
37 Self::Owned(strings) => match other {
38 Self::Owned(other_strings) => strings.eq(other_strings),
39
40 Self::Fostered(other_strings) => {
41 if strings.len() == other_strings.len() {
42 let mut equal = true;
43 for (index, string) in strings.iter().enumerate() {
44 if string.ne(other_strings[index]) {
45 equal = false;
46 break;
47 }
48 }
49 equal
50 } else {
51 false
52 }
53 }
54 },
55
56 Self::Fostered(strings) => match other {
57 Self::Owned(other_strings) => {
58 if strings.len() == other_strings.len() {
59 let mut equal = true;
60 for (index, string) in strings.iter().enumerate() {
61 if string.ne(&other_strings[index]) {
62 equal = false;
63 break;
64 }
65 }
66 equal
67 } else {
68 false
69 }
70 }
71
72 Self::Fostered(other_strings) => strings.eq(other_strings),
73 },
74 }
75 }
76}
77
78impl Eq for FosterStringVector {}
79
80impl PartialOrd for FosterStringVector {
81 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
82 match self {
85 Self::Owned(strings) => match other {
86 Self::Owned(other_strings) => strings.partial_cmp(other_strings),
87
88 Self::Fostered(other_strings) => {
89 let strings_length = strings.len();
90 let other_strings_length = other_strings.len();
91 let length = min(strings_length, other_strings_length);
92
93 let strings_bounded = &strings[..length];
95 let other_strings_bounded = &other_strings[..length];
96
97 for index in 0..length {
98 match strings_bounded[index].as_str().partial_cmp(other_strings_bounded[index]) {
99 Some(Ordering::Equal) => (),
100 not_equal => return not_equal,
101 }
102 }
103
104 strings_length.partial_cmp(&other_strings_length)
105 }
106 },
107
108 Self::Fostered(strings) => match other {
109 Self::Owned(other_strings) => {
110 let strings_length = strings.len();
111 let other_strings_length = other_strings.len();
112 let length = min(strings_length, other_strings_length);
113
114 let strings_bounded = &strings[..length];
116 let other_strings_bounded = &other_strings[..length];
117
118 for index in 0..length {
119 match strings_bounded[index].partial_cmp(other_strings_bounded[index].as_str()) {
120 Some(Ordering::Equal) => (),
121 not_equal => return not_equal,
122 }
123 }
124
125 strings_length.partial_cmp(&other_strings_length)
126 }
127
128 Self::Fostered(other_strings) => strings.partial_cmp(other_strings),
129 },
130 }
131 }
132}
133
134impl Ord for FosterStringVector {
135 fn cmp(&self, other: &Self) -> Ordering {
136 match self {
139 Self::Owned(strings) => match other {
140 Self::Owned(other_strings) => strings.cmp(other_strings),
141
142 Self::Fostered(other_strings) => {
143 let strings_length = strings.len();
144 let other_strings_length = other_strings.len();
145 let length = min(strings_length, other_strings_length);
146
147 let strings_bounded = &strings[..length];
149 let other_strings_bounded = &other_strings[..length];
150
151 for index in 0..length {
152 match strings_bounded[index].as_str().cmp(other_strings_bounded[index]) {
153 Ordering::Equal => (),
154 not_equal => return not_equal,
155 }
156 }
157
158 strings_length.cmp(&other_strings_length)
159 }
160 },
161
162 Self::Fostered(strings) => match other {
163 Self::Owned(other_strings) => {
164 let strings_length = strings.len();
165 let other_strings_length = other_strings.len();
166 let length = min(strings_length, other_strings_length);
167
168 let strings_bounded = &strings[..length];
170 let other_strings_bounded = &other_strings[..length];
171
172 for index in 0..length {
173 match strings_bounded[index].cmp(other_strings_bounded[index].as_str()) {
174 Ordering::Equal => (),
175 not_equal => return not_equal,
176 }
177 }
178
179 strings_length.cmp(&other_strings_length)
180 }
181
182 Self::Fostered(other_strings) => strings.cmp(other_strings),
183 },
184 }
185 }
186}
187
188impl Hash for FosterStringVector {
189 fn hash<HasherT>(&self, state: &mut HasherT)
190 where
191 HasherT: Hasher,
192 {
193 match self {
194 Self::Owned(strings) => {
195 for string in strings {
196 state.write(string.as_bytes());
197 }
198 }
199
200 Self::Fostered(strings) => {
201 for string in strings.iter() {
202 state.write(string.as_bytes());
203 }
204 }
205 }
206 }
207}
208
209impl<'own> IntoIterator for &'own FosterStringVector {
210 type Item = &'own str;
211 type IntoIter =
212 FosterIterator<&'own str, &'own String, &'own &'static str, Iter<'own, String>, Iter<'own, &'static str>>;
213
214 fn into_iter(self) -> Self::IntoIter {
215 match self {
216 Foster::Owned(strings) => Foster::new_owned(ConvertingIterator::new(strings.iter(), |string| &string)),
217 Foster::Fostered(strings) => Foster::new_fostered(ConvertingIterator::new(strings.iter(), |string| string)),
218 }
219 }
220}
221
222#[macro_export]
234macro_rules! delegate_newtype_of_foster_string_vector {
235 ( $type:ty ) => {
236 impl $type {
237 pub fn new_owned(strings: ::std::vec::Vec<::std::string::String>) -> Self {
239 Self(::kutil_std::foster::Foster::new_owned(strings))
240 }
241
242 pub const fn new_fostered(strings: &'static [&'static str]) -> Self {
244 Self(::kutil_std::foster::Foster::new_fostered(strings))
245 }
246 }
247
248 impl ::kutil_std::borrow::IntoOwned for $type {
249 fn into_owned(self) -> Self {
250 match self.0 {
251 ::kutil_std::foster::Foster::Owned(_) => self,
252 ::kutil_std::foster::Foster::Fostered(_) => Self(self.0.into_owned()),
253 }
254 }
255 }
256
257 impl ::kutil_std::foster::HasLength for $type {
258 fn len(&self) -> usize {
259 self.0.len()
260 }
261 }
262
263 impl ::std::convert::From<::std::vec::Vec<::std::string::String>> for $type {
264 fn from(strings: Vec<::std::string::String>) -> Self {
265 strings.into()
266 }
267 }
268
269 impl ::std::cmp::PartialEq for $type {
270 fn eq(&self, other: &Self) -> bool {
271 self.0.eq(&other.0)
272 }
273 }
274
275 impl ::std::cmp::Eq for $type {}
276
277 impl ::std::cmp::PartialOrd for $type {
278 fn partial_cmp(&self, other: &Self) -> ::std::option::Option<::std::cmp::Ordering> {
279 self.0.partial_cmp(&other.0)
280 }
281 }
282
283 impl ::std::cmp::Ord for $type {
284 fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
285 self.0.cmp(&other.0)
286 }
287 }
288
289 impl ::std::hash::Hash for $type {
290 fn hash<HasherT>(&self, state: &mut HasherT)
291 where
292 HasherT: ::std::hash::Hasher,
293 {
294 self.0.hash(state)
295 }
296 }
297
298 impl<'own> ::std::iter::IntoIterator for &'own $type {
299 type Item = &'own str;
300 type IntoIter = ::kutil_std::foster::FosterIterator<
301 &'own str,
302 &'own ::std::string::String,
303 &'own &'static str,
304 ::std::slice::Iter<'own, ::std::string::String>,
305 ::std::slice::Iter<'own, &'static str>,
306 >;
307
308 fn into_iter(self) -> Self::IntoIter {
309 self.0.into_iter()
310 }
311 }
312 };
313}