1use crate::{SeqBytes, SeqBytesIter, SeqBytesIterMut};
2use alloc::{string::String, vec::Vec};
3use core::fmt;
4
5#[derive(Clone, Default, Eq, PartialEq, Hash)]
19pub struct SeqStr {
20 inner: SeqBytes,
21}
22
23impl SeqStr {
24 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn is_empty(&self) -> bool {
31 self.inner.is_empty()
32 }
33
34 pub fn len(&self) -> usize {
36 self.inner.len()
37 }
38
39 pub fn reserve(&mut self, extra: usize) {
41 self.inner.reserve(extra);
42 }
43
44 pub fn shrink_to_fit(&mut self) {
46 self.inner.shrink_to_fit();
47 }
48
49 pub fn get(&self, idx: usize) -> Option<&str> {
51 self.inner
52 .get(idx)
53 .map(|b| unsafe { str::from_utf8_unchecked(b) })
54 }
55
56 pub fn get_mut(&mut self, idx: usize) -> Option<&mut str> {
58 self.inner
59 .get_mut(idx)
60 .map(|b| unsafe { str::from_utf8_unchecked_mut(b) })
61 }
62
63 pub fn contains(&self, s: impl AsRef<str>) -> bool {
65 self.inner.contains(s.as_ref().as_bytes())
66 }
67
68 pub fn push(&mut self, s: impl AsRef<str>) {
70 self.inner.push(s.as_ref().as_bytes());
71 }
72
73 pub fn last(&self) -> Option<&str> {
75 self.inner
76 .last()
77 .map(|b| unsafe { str::from_utf8_unchecked(b) })
78 }
79
80 pub fn pop(&mut self) {
83 self.inner.pop()
84 }
85
86 pub fn range(
92 &self,
93 range_bounds: impl core::ops::RangeBounds<usize>,
94 ) -> core::iter::Map<SeqBytesIter<'_>, fn(&[u8]) -> &str> {
95 fn helper(b: &[u8]) -> &str {
96 unsafe { str::from_utf8_unchecked(b) }
97 }
98
99 self.inner.range(range_bounds).map(helper)
100 }
101
102 pub fn range_mut(
104 &mut self,
105 range_bounds: impl core::ops::RangeBounds<usize>,
106 ) -> core::iter::Map<SeqBytesIterMut<'_>, fn(&mut [u8]) -> &mut str> {
107 fn helper(b: &mut [u8]) -> &mut str {
108 unsafe { str::from_utf8_unchecked_mut(b) }
109 }
110
111 self.inner.range_mut(range_bounds).map(helper)
112 }
113
114 pub fn iter(&self) -> core::iter::Map<SeqBytesIter<'_>, fn(&[u8]) -> &str> {
116 fn helper(b: &[u8]) -> &str {
117 unsafe { str::from_utf8_unchecked(b) }
118 }
119
120 self.inner.iter().map(helper)
121 }
122
123 pub fn iter_mut(&mut self) -> core::iter::Map<SeqBytesIterMut<'_>, fn(&mut [u8]) -> &mut str> {
125 fn helper(b: &mut [u8]) -> &mut str {
126 unsafe { str::from_utf8_unchecked_mut(b) }
127 }
128
129 self.inner.iter_mut().map(helper)
130 }
131
132 pub fn chunks(
137 &self,
138 chunk_size: usize,
139 ) -> impl Clone + ExactSizeIterator<Item = impl Clone + ExactSizeIterator<Item = &str>> {
140 fn helper(b: &[u8]) -> &str {
141 unsafe { str::from_utf8_unchecked(b) }
142 }
143
144 self.inner.chunks(chunk_size).map(|iter| iter.map(helper))
145 }
146
147 pub fn truncate(&mut self, new_size: usize) {
149 self.inner.truncate(new_size)
150 }
151
152 pub fn resize(&mut self, new_size: usize) {
154 self.inner.resize(new_size)
155 }
156
157 pub fn retain(&mut self, mut pred: impl FnMut(&str) -> bool) {
160 self.inner
161 .retain(move |b| pred(unsafe { str::from_utf8_unchecked(b) }));
162 }
163
164 pub fn retain_mut(&mut self, mut pred: impl FnMut(&mut str) -> bool) {
167 self.inner
168 .retain_mut(move |b| pred(unsafe { str::from_utf8_unchecked_mut(b) }));
169 }
170
171 pub fn in_place_writer(&mut self) -> impl core::fmt::Write {
174 struct Sink<T: FnMut(&[u8])>(pub T);
176
177 impl<T: FnMut(&[u8])> core::fmt::Write for Sink<T> {
178 fn write_str(&mut self, s: &str) -> std::fmt::Result {
179 (self.0)(s.as_bytes());
180 Ok(())
181 }
182 }
183
184 Sink(self.inner.in_place_writer_no_std())
185 }
186
187 pub fn from_display_iter<T: core::fmt::Display, I: Iterator<Item = T>>(it: I) -> Self {
190 use core::fmt::Write;
191
192 let mut result = Self::default();
193 result.reserve(it.size_hint().0);
194 for item in it {
195 write!(result.in_place_writer(), "{item}")
198 .expect("a Display implementation returned an error unexpectedly");
199 }
200 result
201 }
202
203 pub fn as_vec(&self) -> Vec<&str> {
210 self.iter().collect()
211 }
212
213 pub fn concat(&self) -> &str {
215 unsafe { core::str::from_utf8_unchecked(self.inner.concat()) }
216 }
217
218 pub fn join(&self, separator: &str) -> String {
220 let mut result = String::with_capacity(
221 self.inner.num_bytes() + self.inner.len().saturating_sub(1) * separator.len(),
222 );
223 let mut first = true;
224
225 for s in self.iter() {
226 if first {
227 first = false;
228 } else {
229 result += separator;
230 }
231 result += s;
232 }
233 result
234 }
235}
236
237impl core::ops::Index<usize> for SeqStr {
238 type Output = str;
239
240 fn index(&self, index: usize) -> &str {
241 unsafe { str::from_utf8_unchecked(self.inner.index(index)) }
242 }
243}
244
245impl core::ops::IndexMut<usize> for SeqStr {
246 fn index_mut(&mut self, index: usize) -> &mut str {
247 unsafe { str::from_utf8_unchecked_mut(self.inner.index_mut(index)) }
248 }
249}
250
251impl fmt::Debug for SeqStr {
252 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
253 f.debug_list().entries(self.iter()).finish()
254 }
255}
256
257impl<A: AsRef<str>> Extend<A> for SeqStr {
258 fn extend<T>(&mut self, iter: T)
259 where
260 T: IntoIterator<Item = A>,
261 {
262 let iter = iter.into_iter();
263 self.reserve(iter.size_hint().0);
264 for item in iter {
265 self.push(item);
266 }
267 }
268}
269
270impl<A: AsRef<str>> FromIterator<A> for SeqStr {
271 fn from_iter<T>(iter: T) -> Self
273 where
274 T: IntoIterator<Item = A>,
275 {
276 let mut result = SeqStr::default();
277 result.extend(iter);
278 result
279 }
280}
281
282impl<'a> IntoIterator for &'a SeqStr {
285 type Item = &'a str;
286 type IntoIter = core::iter::Map<SeqBytesIter<'a>, fn(&[u8]) -> &str>;
287
288 fn into_iter(self) -> Self::IntoIter {
289 fn helper(b: &[u8]) -> &str {
290 unsafe { core::str::from_utf8_unchecked(b) }
291 }
292
293 self.inner.iter().map(helper)
294 }
295}
296
297#[cfg(feature = "serde")]
298mod serde_impls {
299 use super::*;
300 use ::serde::{
301 Deserialize, Serialize,
302 de::{Deserializer, SeqAccess, Visitor},
303 ser::{SerializeSeq, Serializer},
304 };
305
306 impl Serialize for SeqStr {
307 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
308 where
309 S: Serializer,
310 {
311 let mut seq = serializer.serialize_seq(Some(self.len()))?;
312 for e in self {
313 seq.serialize_element(e)?;
314 }
315 seq.end()
316 }
317 }
318
319 impl<'de> Deserialize<'de> for SeqStr {
320 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
321 where
322 D: Deserializer<'de>,
323 {
324 deserializer.deserialize_seq(SeqStrVis {})
325 }
326 }
327
328 struct SeqStrVis {}
329
330 impl<'de> Visitor<'de> for SeqStrVis {
331 type Value = SeqStr;
332
333 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
334 formatter.write_str("a sequence of strings")
335 }
336
337 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
338 where
339 A: SeqAccess<'de>,
340 {
341 let mut result = SeqStr::default();
342
343 if let Some(size) = seq.size_hint() {
344 result.reserve(size);
345 }
346
347 loop {
348 let maybe_next_str: Option<&str> = seq.next_element()?;
349 if let Some(next_str) = maybe_next_str {
350 result.push(next_str);
351 } else {
352 return Ok(result);
353 }
354 }
355 }
356 }
357}
358
359#[cfg(test)]
360mod tests {
361 use super::*;
362 use alloc::{borrow::ToOwned, vec, vec::Vec};
363
364 #[test]
365 fn vec_str_conversions() {
366 let vec_str = vec!["1", "2", "3"];
367
368 let seq_str: SeqStr = vec_str.into_iter().collect();
369
370 assert_eq!(seq_str.len(), 3);
371 assert_eq!(&seq_str[0], "1");
372 assert_eq!(&seq_str[1], "2");
373 assert_eq!(&seq_str[2], "3");
374
375 let vec_str2 = seq_str.iter().map(ToOwned::to_owned).collect::<Vec<_>>();
376
377 assert_eq!(vec_str2.len(), 3);
378 assert_eq!(vec_str2[0], "1");
379 assert_eq!(vec_str2[1], "2");
380 assert_eq!(vec_str2[2], "3");
381 }
382
383 #[test]
384 fn vec_string_conversions() {
385 let vec_string = vec!["1".to_owned(), "2".to_owned(), "3".to_owned()];
386
387 let seq_str: SeqStr = vec_string.into_iter().collect();
388
389 assert_eq!(seq_str.len(), 3);
390 assert_eq!(&seq_str[0], "1");
391 assert_eq!(&seq_str[1], "2");
392 assert_eq!(&seq_str[2], "3");
393
394 let vec_str2 = seq_str.iter().map(ToOwned::to_owned).collect::<Vec<_>>();
395
396 assert_eq!(vec_str2.len(), 3);
397 assert_eq!(vec_str2[0], "1");
398 assert_eq!(vec_str2[1], "2");
399 assert_eq!(vec_str2[2], "3");
400 }
401
402 #[test]
403 fn from_display_iter() {
404 let v = vec![1, 2, 3, 45, 67];
405
406 let seq_str = SeqStr::from_display_iter(v.into_iter());
407
408 assert_eq!(seq_str.len(), 5);
409 assert_eq!(&seq_str[0], "1");
410 assert_eq!(&seq_str[1], "2");
411 assert_eq!(&seq_str[2], "3");
412 assert_eq!(&seq_str[3], "45");
413 assert_eq!(&seq_str[4], "67");
414 }
415
416 #[test]
417 fn range() {
418 let v = vec![1, 2, 3, 45, 67];
419
420 let seq_str = SeqStr::from_display_iter(v.into_iter());
421
422 let seq_str2: SeqStr = seq_str.range(1..4).collect();
423 assert_eq!(seq_str2.len(), 3);
424 assert_eq!(&seq_str2[0], "2");
425 assert_eq!(&seq_str2[1], "3");
426 assert_eq!(&seq_str2[2], "45");
427
428 let seq_str2: SeqStr = seq_str.range(3..).collect();
429 assert_eq!(seq_str2.len(), 2);
430 assert_eq!(&seq_str2[0], "45");
431 assert_eq!(&seq_str2[1], "67");
432
433 let seq_str2: SeqStr = seq_str.range(..3).collect();
434 assert_eq!(seq_str2.len(), 3);
435 assert_eq!(&seq_str2[0], "1");
436 assert_eq!(&seq_str2[1], "2");
437 assert_eq!(&seq_str2[2], "3");
438
439 let seq_str2: SeqStr = seq_str.range(..).collect();
440 assert_eq!(seq_str2.len(), 5);
441 assert_eq!(&seq_str2[0], "1");
442 assert_eq!(&seq_str2[1], "2");
443 assert_eq!(&seq_str2[2], "3");
444 assert_eq!(&seq_str2[3], "45");
445 assert_eq!(&seq_str2[4], "67");
446 }
447
448 #[test]
449 fn iter_mut() {
450 let mut seq_str = SeqStr::from_iter(["asdf", "jkl;", ""]);
451
452 assert_eq!(seq_str.len(), 3);
453 assert_eq!(&seq_str[0], "asdf");
454 assert_eq!(&seq_str[1], "jkl;");
455 assert_eq!(&seq_str[2], "");
456
457 for s in seq_str.iter_mut() {
458 s.make_ascii_uppercase();
459 }
460
461 assert_eq!(seq_str.len(), 3);
462 assert_eq!(&seq_str[0], "ASDF");
463 assert_eq!(&seq_str[1], "JKL;");
464 assert_eq!(&seq_str[2], "");
465 }
466
467 #[test]
468 fn test_serde() {
469 let seq_str: SeqStr = serde_json::from_str("[\"asdf\", \"jkl;\", \"\"]").unwrap();
470
471 assert_eq!(seq_str.len(), 3);
472 assert_eq!(&seq_str[0], "asdf");
473 assert_eq!(&seq_str[1], "jkl;");
474 assert_eq!(&seq_str[2], "");
475
476 let ser = serde_json::to_string(&seq_str).unwrap();
477
478 let seq_str2: SeqStr = serde_json::from_str(&ser).unwrap();
479
480 assert_eq!(seq_str, seq_str2);
481 }
482
483 #[test]
484 fn test_join() {
485 let seq_str = SeqStr::from_iter(["asdf", "jkl;", "", ":)"]);
486
487 assert_eq!(seq_str.concat(), "asdfjkl;:)");
488 assert_eq!(seq_str.join(", "), "asdf, jkl;, , :)");
489 }
490}