buni-rs 1.1.1

Reference Buni serializer / deserializer in Rust
Documentation
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>())
    }
}