use crate::parsing::ExtractedToken;
#[derive(Debug, Copy, Clone)]
pub struct FullText<'t> {
text: &'t str,
}
impl<'t> FullText<'t> {
#[inline]
pub fn new(text: &'t str) -> Self {
FullText { text }
}
#[inline]
#[doc(hidden)]
pub(crate) fn inner(&self) -> &'t str {
self.text
}
pub fn slice(
&self,
start_token: &ExtractedToken,
end_token: &ExtractedToken,
) -> &'t str {
let start = start_token.span.start;
let end = end_token.span.end;
self.slice_impl("full", start, end)
}
pub fn slice_partial(
&self,
start_token: &ExtractedToken,
end_token: &ExtractedToken,
) -> &'t str {
let start = start_token.span.start;
let end = end_token.span.start;
self.slice_impl("partial", start, end)
}
fn slice_impl(&self, slice_kind: &'static str, start: usize, end: usize) -> &'t str {
debug!("Extracting {slice_kind} slice ({start}-{end}) from full text");
assert!(
start <= end,
"Starting index is later than the ending index: {start} > {end}",
);
&self.text[start..end]
}
#[inline]
pub fn len(&self) -> usize {
self.text.len()
}
}
#[test]
fn slice() {
use crate::parsing::Token;
let text = "Apple banana!";
let full_text = FullText::new(text);
macro_rules! range {
($span:expr) => {
&ExtractedToken {
token: Token::Other,
slice: &text[$span],
span: $span,
}
};
}
{
let slice = full_text.slice(range!(0..1), range!(4..5));
assert_eq!(slice, "Apple", "Full slice didn't match expected");
}
{
let slice = full_text.slice_partial(range!(6..9), range!(12..13));
assert_eq!(slice, "banana", "Partial slice didn't match expected");
}
}
#[test]
#[should_panic]
fn slice_invalid() {
use crate::parsing::Token;
let text = "Durian...";
let full_text = FullText::new(text);
macro_rules! range {
($span:expr) => {
&ExtractedToken {
token: Token::Other,
slice: &text[$span],
span: $span,
}
};
}
let _ = full_text.slice(range!(6..7), range!(0..1));
}
#[test]
#[should_panic]
fn slice_partial_invalid() {
use crate::parsing::Token;
let text = "Eggplant!";
let full_text = FullText::new(text);
macro_rules! range {
($span:expr) => {
&ExtractedToken {
token: Token::Other,
slice: &text[$span],
span: $span,
}
};
}
let _ = full_text.slice_partial(range!(8..9), range!(2..4));
}