use alloc::boxed::Box;
use alloc::string::String;
use core::fmt::{Debug, Display, Formatter};
use core::iter::Enumerate;
use nom::{Compare, CompareResult, Input, Needed};
#[derive(Debug)]
pub struct DynIndexTracker<'a, T> {
pub inner: Enumerate<DynIter<'a, T>>,
pub index: usize,
pub length: usize
}
impl<'a, T> Iterator for DynIndexTracker<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
match self.inner.next() {
None => None,
Some(value) => {
self.index = value.0;
Option::from(value.1)
}
}
}
}
impl<'a, T> Clone for DynIndexTracker<'a, T> {
fn clone(&self) -> Self {
DynIndexTracker {
inner: self.inner.clone(),
index: self.index,
length: self.length
}
}
}
#[derive(Debug)]
pub struct DynIter<'a, T> {
pub
inner: Box<dyn IterClone<'a, T> + 'a>,
}
impl<'a, T> Iterator for DynIter<'a, T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
impl<'a, T> Clone for DynIter<'a, T> {
fn clone(&self) -> Self {
self.inner.dyn_clone()
}
}
pub trait IterClone<'a, T>: Iterator<Item = T> + Debug {
fn dyn_clone(&self) -> DynIter<'a, T>;
}
impl<'a, I, T> IterClone<'a, T> for I
where I: Iterator<Item = T> + Clone + Debug + 'a {
fn dyn_clone(&self) -> DynIter<'a, T> {
DynIter {
inner: Box::new(self.clone())
}
}
}
#[derive(Debug)]
pub struct IterAdapter<'a, T> {
pub inner: DynIndexTracker<'a, T>,
}
impl<'a, T> Clone for IterAdapter<'a, T> {
fn clone(&self) -> Self {
IterAdapter { inner: self.inner.clone() }
}
}
impl<'a, T> IterAdapter<'a, T> {
fn get_iter(&self) -> DynIndexTracker<'a, T> {
self.inner.clone()
}
}
impl<'a> FromIterator<IterAdapter<'a, char>> for String {
fn from_iter<T: IntoIterator<Item=IterAdapter<'a, char>>>(iter: T) -> Self {
iter.into_iter().map(|i| {
i.get_iter().collect::<String>()
}).collect()
}
}
impl<'a> Input for IterAdapter<'a, char> {
type Item = char;
type Iter = DynIndexTracker<'a, char>;
type IterIndices = Enumerate<DynIter<'a, char>>;
fn input_len(&self) -> usize {
self.inner.length
}
fn take(&self, index: usize) -> Self {
IterAdapter {
inner: DynIndexTracker {
inner: DynIter {
inner: Box::from(self.get_iter().take(index))
}.enumerate(),
index: 0,
length: index
}
}
}
fn take_from(&self, index: usize) -> Self {
IterAdapter {
inner: DynIndexTracker {
inner: DynIter {
inner: Box::from(self.get_iter().skip(index))
}.enumerate(),
index: 0,
length: self.inner.length - index
}
}
}
fn take_split(&self, index: usize) -> (Self, Self) {
(
self.take_from(index),
self.take(index),
)
}
fn position<P>(&self, predicate: P) -> Option<usize>
where
P: Fn(Self::Item) -> bool
{
self.get_iter().position(predicate)
}
fn iter_elements(&self) -> Self::Iter {
self.get_iter()
}
fn iter_indices(&self) -> Self::IterIndices {
self.get_iter().inner
}
fn slice_index(&self, count: usize) -> Result<usize, Needed> {
if self.inner.length >= count {
Ok(count)
} else {
Err(Needed::new(count - self.inner.length))
}
}
}
impl<'a> Compare<&'a str> for IterAdapter<'a, char> {
fn compare(&self, t: &'a str) -> CompareResult {
match self.get_iter().zip(t.iter_elements()).position(|(a, b)| a != b) {
None => if self.inner.length >= t.len() {
CompareResult::Ok
} else {
CompareResult::Incomplete
}
Some(_) => CompareResult::Error
}
}
fn compare_no_case(&self, t: &'a str) -> CompareResult {
match self.get_iter().zip(t.iter_elements()).position(|(a, b)| a.to_lowercase().ne(b.to_lowercase())) {
None => if self.inner.length >= t.len() {
CompareResult::Ok
} else {
CompareResult::Incomplete
}
Some(_) => CompareResult::Error
}
}
}
impl<'a> Display for IterAdapter<'a, char> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.get_iter().collect::<String>())
}
}