use core::fmt;
use core::ops::Range;
#[must_use]
#[derive(Clone, Copy, PartialEq)]
pub struct StrSpan<'a> {
text: &'a str,
span: &'a str,
start: usize,
}
impl<'a> From<&'a str> for StrSpan<'a> {
#[inline]
fn from(text: &'a str) -> Self {
StrSpan {
text,
start: 0,
span: text,
}
}
}
impl<'a> StrSpan<'a> {
#[inline]
pub(crate) fn from_substr(text: &str, start: usize, end: usize) -> StrSpan {
debug_assert!(start <= end);
StrSpan { text, span: &text[start..end], start }
}
#[inline]
pub fn start(&self) -> usize {
self.start
}
#[inline]
pub fn end(&self) -> usize {
self.start + self.span.len()
}
#[inline]
pub fn range(&self) -> Range<usize> {
self.start..self.end()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.span.is_empty()
}
#[inline]
pub fn as_str(&self) -> &'a str {
&self.span
}
#[inline]
pub(crate) fn as_bytes(&self) -> &'a [u8] {
self.span.as_bytes()
}
#[inline]
pub fn full_str(&self) -> &'a str {
self.text
}
#[inline]
pub(crate) fn slice_region(&self, start: usize, end: usize) -> StrSpan<'a> {
let start = self.start + start;
let end = self.start + end;
StrSpan::from_substr(self.text, start, end)
}
}
impl<'a> fmt::Debug for StrSpan<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "StrSpan({:?} {}..{})", self.as_str(), self.start(), self.end())
}
}
impl<'a> fmt::Display for StrSpan<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}