use crate::input::{Cursor, Input};
mod bound;
pub use bound::{BoundSpan, ReadError, ReadProgress};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Span {
start: usize,
end: usize,
}
impl Span {
pub fn new(start: usize, end: usize) -> Option<Self> {
(start <= end).then_some(Self { start, end })
}
pub fn start(self) -> usize {
self.start
}
pub fn end(self) -> usize {
self.end
}
pub fn len(self) -> usize {
self.end - self.start
}
pub fn is_empty(self) -> bool {
self.start == self.end
}
pub fn units(self, input: Input<'_>) -> Option<SpanUnits<'_>> {
if self.end > input.len_utf16() {
return None;
}
Some(SpanUnits {
cursor: input.cursor_at(self.start)?,
remaining: self.len(),
})
}
}
#[derive(Clone, Debug)]
pub struct SpanUnits<'a> {
cursor: Cursor<'a>,
remaining: usize,
}
impl Iterator for SpanUnits<'_> {
type Item = u16;
fn next(&mut self) -> Option<Self::Item> {
if self.remaining == 0 {
return None;
}
self.remaining -= 1;
self.cursor.next_unit()
}
fn size_hint(&self) -> (usize, Option<usize>) {
(self.remaining, Some(self.remaining))
}
}
impl ExactSizeIterator for SpanUnits<'_> {}
impl core::iter::FusedIterator for SpanUnits<'_> {}