use alloc::boxed::Box;
use alloc::string::{String, ToString};
use core::cell::Cell;
use nom::{Compare, CompareResult, Input, Needed};
use core::fmt::{Debug, Display, Formatter};
use core::iter::Enumerate;
#[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(index),
self.take_from(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 {
if self.input_len() <= self.inner.length {
CompareResult::Incomplete
} else if self.to_string() == t {
CompareResult::Ok
} else {
CompareResult::Error
}
}
fn compare_no_case(&self, t: &'a str) -> CompareResult {
if self.input_len() <= self.inner.length {
CompareResult::Incomplete
} else if self.to_string().to_lowercase() == t.to_lowercase() {
CompareResult::Ok
} else {
CompareResult::Error
}
}
}
impl<'a> Display for IterAdapter<'a, char> {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", self.to_string())
}
}
pub struct ElementIterator<T> {
element: Cell<Option<T>>
}
impl<T> ElementIterator<T> {
pub fn new(element: T) -> Self {
ElementIterator {
element: Cell::new(Some(element))
}
}
}
impl<T> Iterator for ElementIterator<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.element.take()
}
}