use core::fmt::{self, Write as _};
use core::ops::RangeBounds;
use crate::range::CharsRange;
use crate::utf8::REPLACEMENT_CHAR_STR;
use crate::{PartialHandling, StrQueue};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Fragment<'a> {
Str(&'a str),
Char(char),
Incomplete,
}
impl fmt::Display for Fragment<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Self::Str(s) => f.write_str(s),
Self::Char(c) => f.write_char(c),
Self::Incomplete => f.write_str(REPLACEMENT_CHAR_STR),
}
}
}
#[derive(Debug, Clone)]
pub struct Fragments<'a> {
range: CharsRange<'a>,
}
impl<'a> Fragments<'a> {
#[inline]
#[must_use]
pub(crate) fn new<R>(queue: &'a StrQueue, range: R, partial_handling: PartialHandling) -> Self
where
R: RangeBounds<usize>,
{
let mut range = queue.chars_range(range);
if partial_handling.is_ignore() {
range.trim_last_incomplete_char();
}
Self { range }
}
#[inline]
#[must_use]
pub(crate) fn from_range(range: CharsRange<'a>) -> Self {
Self { range }
}
}
impl<'a> Iterator for Fragments<'a> {
type Item = Fragment<'a>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
self.range.pop_fragment()
}
}
impl fmt::Display for Fragments<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.clone().try_for_each(|frag| frag.fmt(f))
}
}
impl<'a> From<CharsRange<'a>> for Fragments<'a> {
#[inline]
fn from(range: CharsRange<'a>) -> Self {
Self { range }
}
}