str_queue/iter/
fragments.rs1use core::fmt::{self, Write as _};
4use core::ops::RangeBounds;
5
6use crate::range::CharsRange;
7use crate::utf8::REPLACEMENT_CHAR_STR;
8use crate::{PartialHandling, StrQueue};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12pub enum Fragment<'a> {
13 Str(&'a str),
15 Char(char),
17 Incomplete,
21}
22
23impl fmt::Display for Fragment<'_> {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match *self {
26 Self::Str(s) => f.write_str(s),
27 Self::Char(c) => f.write_char(c),
28 Self::Incomplete => f.write_str(REPLACEMENT_CHAR_STR),
29 }
30 }
31}
32
33#[derive(Debug, Clone)]
35pub struct Fragments<'a> {
36 range: CharsRange<'a>,
38}
39
40impl<'a> Fragments<'a> {
41 #[inline]
43 #[must_use]
44 pub(crate) fn new<R>(queue: &'a StrQueue, range: R, partial_handling: PartialHandling) -> Self
45 where
46 R: RangeBounds<usize>,
47 {
48 let mut range = queue.chars_range(range);
49 if partial_handling.is_ignore() {
50 range.trim_last_incomplete_char();
51 }
52 Self { range }
53 }
54
55 #[inline]
57 #[must_use]
58 pub(crate) fn from_range(range: CharsRange<'a>) -> Self {
59 Self { range }
60 }
61}
62
63impl<'a> Iterator for Fragments<'a> {
64 type Item = Fragment<'a>;
65
66 #[inline]
67 fn next(&mut self) -> Option<Self::Item> {
68 self.range.pop_fragment()
69 }
70}
71
72impl fmt::Display for Fragments<'_> {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 self.clone().try_for_each(|frag| frag.fmt(f))
75 }
76}
77
78impl<'a> From<CharsRange<'a>> for Fragments<'a> {
79 #[inline]
80 fn from(range: CharsRange<'a>) -> Self {
81 Self { range }
82 }
83}