use nom::{
Compare, CompareResult, FindSubstring, InputIter, InputLength, InputTake, Needed, Offset,
Slice, UnspecializedInput,
};
use std::ops::{RangeFrom, RangeTo};
use std::str::{CharIndices, Chars};
#[derive(Copy, Clone, Debug)]
pub struct Input<'a> {
pub value: &'a str,
pub depth: usize,
}
impl InputLength for Input<'_> {
fn input_len(&self) -> usize {
self.value.len()
}
}
impl InputTake for Input<'_> {
fn take(&self, count: usize) -> Self {
Self {
value: self.value.take(count),
depth: self.depth,
}
}
fn take_split(&self, count: usize) -> (Self, Self) {
let (a, b) = self.value.take_split(count);
(
Self {
value: a,
depth: self.depth,
},
Self {
value: b,
depth: self.depth,
},
)
}
}
impl<'a> InputIter for Input<'a> {
type Item = char;
type Iter = CharIndices<'a>;
type IterElem = Chars<'a>;
fn iter_indices(&self) -> Self::Iter {
self.value.iter_indices()
}
fn iter_elements(&self) -> Self::IterElem {
self.value.iter_elements()
}
fn position<P>(&self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool,
{
self.value.position(predicate)
}
fn slice_index(&self, count: usize) -> Result<usize, Needed> {
self.value.slice_index(count)
}
}
impl UnspecializedInput for Input<'_> {
}
impl<'a> Compare<&'a str> for Input<'a> {
fn compare(&self, t: &'a str) -> CompareResult {
self.value.compare(t)
}
fn compare_no_case(&self, t: &'a str) -> CompareResult {
self.value.compare_no_case(t)
}
}
impl<'a> From<(&'a str, usize)> for Input<'a> {
fn from(value: (&'a str, usize)) -> Self {
Self {
value: value.0,
depth: value.1,
}
}
}
impl Slice<RangeFrom<usize>> for Input<'_> {
fn slice(&self, range: RangeFrom<usize>) -> Self {
Self {
value: self.value.slice(range),
depth: self.depth,
}
}
}
impl Slice<RangeTo<usize>> for Input<'_> {
fn slice(&self, range: RangeTo<usize>) -> Self {
Self {
value: self.value.slice(range),
depth: self.depth,
}
}
}
impl Offset for Input<'_> {
fn offset(&self, second: &Self) -> usize {
self.value.offset(second.value)
}
}
impl<'a> FindSubstring<&'a str> for Input<'a> {
fn find_substring(&self, substr: &'a str) -> Option<usize> {
self.value.find_substring(substr)
}
}