use alloc::boxed::Box;
use core::fmt::Debug;
use core::iter::{Empty, Fuse, TakeWhile};
use core::marker::PhantomData;
use crate::curve::curve_types::{CurveType, UnspecifiedCurve};
use crate::iterators::curve::FromCurveIterator;
use crate::iterators::join::JoinAdjacentIterator;
use crate::window::window_types::WindowType;
use crate::window::Window;
use core::ops::DerefMut;
pub mod curve;
pub mod join;
pub mod peek;
pub mod server;
pub mod task;
pub trait CurveIterator: Debug {
type CurveKind: CurveType;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>>;
#[must_use]
fn collect_curve<R: FromCurveIterator<Self::CurveKind>>(self) -> R
where
Self: Sized,
{
R::from_curve_iter(self)
}
#[must_use]
fn reclassify<O>(self) -> ReclassifyIterator<Self, O>
where
Self: Sized,
{
ReclassifyIterator {
iter: self,
phantom: PhantomData,
}
}
fn normalize(
self,
) -> JoinAdjacentIterator<
CurveIteratorIterator<Self>,
<Self::CurveKind as CurveType>::WindowKind,
Self::CurveKind,
>
where
Self: Sized,
{
JoinAdjacentIterator::new_from_curve(self)
}
fn take_while_curve<F>(self, fun: F) -> TakeWhile<CurveIteratorIterator<Self>, F>
where
Self: Sized,
F: for<'a> FnMut(&'a Window<<Self::CurveKind as CurveType>::WindowKind>) -> bool,
{
self.into_iterator().take_while(fun)
}
fn fuse_curve(self) -> Fuse<CurveIteratorIterator<Self>>
where
Self: Sized,
{
self.into_iterator().fuse()
}
fn into_iterator(self) -> CurveIteratorIterator<Self>
where
Self: Sized,
{
CurveIteratorIterator { iter: self }
}
}
pub trait ClonableCurveIterator<'b>: CurveIterator + 'b {
fn clone_box(&self) -> Box<dyn ClonableCurveIterator<'b, CurveKind = Self::CurveKind> + 'b>;
}
impl<'b, T> ClonableCurveIterator<'b> for T
where
T: 'b + CurveIterator + Clone,
{
fn clone_box(&self) -> Box<dyn ClonableCurveIterator<'b, CurveKind = Self::CurveKind> + 'b> {
Box::new(self.clone())
}
}
impl<'a, C: CurveType> Clone for Box<dyn ClonableCurveIterator<'a, CurveKind = C> + 'a>
where
C: 'a,
{
fn clone(&self) -> Self {
self.clone_box()
}
}
#[derive(Debug)]
pub struct ReclassifyIterator<I, O> {
iter: I,
phantom: PhantomData<O>,
}
impl<I: Clone, O> Clone for ReclassifyIterator<I, O> {
fn clone(&self) -> Self {
ReclassifyIterator {
iter: self.iter.clone(),
phantom: PhantomData,
}
}
}
impl<I, O> CurveIterator for ReclassifyIterator<I, O>
where
I: CurveIterator,
O: CurveType,
{
type CurveKind = O;
fn next_window(&mut self) -> Option<Window<O::WindowKind>> {
self.iter.next_window().map(Window::reclassify)
}
}
#[derive(Debug, Clone)]
pub struct CurveIteratorIterator<I> {
iter: I,
}
impl<I> CurveIterator for CurveIteratorIterator<I>
where
I: CurveIterator,
{
type CurveKind = I::CurveKind;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
self.iter.next_window()
}
}
impl<CI: CurveIterator> CurveIterator for &mut CI {
type CurveKind = CI::CurveKind;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
CI::next_window(self)
}
}
impl<CI: CurveIterator> CurveIterator for Box<CI> {
type CurveKind = CI::CurveKind;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
CI::next_window(self)
}
}
impl<'b, C> CurveIterator for Box<dyn ClonableCurveIterator<'b, CurveKind = C>>
where
C: CurveType,
{
type CurveKind = C;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
self.deref_mut().next_window()
}
}
impl<I> Iterator for CurveIteratorIterator<I>
where
I: CurveIterator,
{
type Item = Window<<I::CurveKind as CurveType>::WindowKind>;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next_window()
}
}
impl<W> CurveIterator for Empty<Window<W>>
where
W: WindowType,
{
type CurveKind = UnspecifiedCurve<W>;
fn next_window(&mut self) -> Option<Window<W>> {
None
}
}
impl<W: WindowType, CI> CurveIterator for Fuse<CI>
where
CI: CurveIterator + Iterator<Item = Window<W>>,
CI::CurveKind: CurveType<WindowKind = W>,
{
type CurveKind = CI::CurveKind;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
self.next()
}
}
impl<W, P, CI> CurveIterator for TakeWhile<CI, P>
where
W: WindowType,
P: for<'r> FnMut(&'r Window<W>) -> bool,
CI: CurveIterator + Iterator<Item = Window<W>>,
CI::CurveKind: CurveType<WindowKind = W>,
{
type CurveKind = CI::CurveKind;
fn next_window(&mut self) -> Option<Window<<Self::CurveKind as CurveType>::WindowKind>> {
self.next()
}
}