use futures_util::Future; use futures_util::FutureExt; use futures_util::Stream; use futures_util::StreamExt; use items_0::collect_s::Collectable; use items_0::streamitem::RangeCompletableItem; use items_0::streamitem::Sitemty; use items_0::streamitem::StreamItem; use items_0::transform::CollectableStreamTrait; use items_0::transform::EventStreamTrait; use items_0::transform::EventTransform; use items_0::transform::TransformProperties; use items_0::transform::WithTransformProperties; use items_0::Events; use std::collections::VecDeque; use std::pin::Pin; use std::task::Context; use std::task::Poll; pub struct Enumerate2 { inp: T, cnt: usize, } impl Enumerate2 { pub fn new(inp: T) -> Self where T: EventTransform, { Self { inp, cnt: 0 } } } impl Stream for Enumerate2 where T: Stream + Unpin, { type Item = (usize, ::Item); fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { use Poll::*; match self.inp.poll_next_unpin(cx) { Ready(Some(item)) => { let i = self.cnt; self.cnt += 1; Ready(Some((i, item))) } Ready(None) => Ready(None), Pending => Pending, } } } impl WithTransformProperties for Enumerate2 where T: WithTransformProperties, { fn query_transform_properties(&self) -> TransformProperties { self.inp.query_transform_properties() } } impl EventTransform for Enumerate2 where T: WithTransformProperties + Send, { fn transform(&mut self, src: Box) -> Box { todo!() } } pub struct Then2 { inp: Pin>, f: Pin>, fut: Option>>, } impl Then2 where T: Stream, F: Fn(::Item) -> Fut, { pub fn new(inp: T, f: F) -> Self where T: EventTransform, { Self { inp: Box::pin(inp), f: Box::pin(f), fut: None, } } fn prepare_fut(&mut self, item: ::Item) { self.fut = Some(Box::pin((self.f)(item))); } } /*impl Unpin for Then2 where T: Unpin, F: Unpin, Fut: Unpin, { }*/ impl Stream for Then2 where T: Stream, F: Fn(::Item) -> Fut, Fut: Future, { type Item = ::Output; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { use Poll::*; loop { break if let Some(fut) = self.fut.as_mut() { match fut.poll_unpin(cx) { Ready(item) => { self.fut = None; Ready(Some(item)) } Pending => Pending, } } else { match self.inp.poll_next_unpin(cx) { Ready(Some(item)) => { self.prepare_fut(item); continue; } Ready(None) => Ready(None), Pending => Pending, } }; } } } impl WithTransformProperties for Then2 where T: EventTransform, { fn query_transform_properties(&self) -> TransformProperties { self.inp.query_transform_properties() } } impl EventTransform for Then2 where T: EventTransform + Send, F: Send, Fut: Send, { fn transform(&mut self, src: Box) -> Box { todo!() } } pub trait TransformerExt { fn enumerate2(self) -> Enumerate2 where Self: EventTransform + Sized; fn then2(self, f: F) -> Then2 where Self: EventTransform + Stream + Sized, F: Fn(::Item) -> Fut, Fut: Future; } impl TransformerExt for T { fn enumerate2(self) -> Enumerate2 where Self: EventTransform + Sized, { Enumerate2::new(self) } fn then2(self, f: F) -> Then2 where Self: EventTransform + Stream + Sized, F: Fn(::Item) -> Fut, Fut: Future, { Then2::new(self, f) } } pub struct VecStream { inp: VecDeque, } impl VecStream { pub fn new(inp: VecDeque) -> Self { Self { inp } } } /*impl Unpin for VecStream where T: Unpin {}*/ impl Stream for VecStream where T: Unpin, { type Item = T; fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context) -> Poll> { use Poll::*; if let Some(item) = self.inp.pop_front() { Ready(Some(item)) } else { Ready(None) } } } impl WithTransformProperties for VecStream { fn query_transform_properties(&self) -> TransformProperties { todo!() } } impl EventTransform for VecStream where T: Send, { fn transform(&mut self, src: Box) -> Box { todo!() } } /// Wrap any event stream and provide transformation properties. pub struct PlainEventStream where T: Events, INP: Stream>, { inp: Pin>, } impl PlainEventStream where T: Events, INP: Stream>, { pub fn new(inp: INP) -> Self { Self { inp: Box::pin(inp) } } } impl Stream for PlainEventStream where T: Events, INP: Stream>, { type Item = Sitemty>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll> { use Poll::*; match self.inp.poll_next_unpin(cx) { Ready(Some(item)) => Ready(Some(match item { Ok(item) => Ok(match item { StreamItem::DataItem(item) => StreamItem::DataItem(match item { RangeCompletableItem::RangeComplete => RangeCompletableItem::RangeComplete, RangeCompletableItem::Data(item) => RangeCompletableItem::Data(Box::new(item)), }), StreamItem::Log(item) => StreamItem::Log(item), StreamItem::Stats(item) => StreamItem::Stats(item), }), Err(e) => Err(e), })), Ready(None) => Ready(None), Pending => Pending, } } } impl WithTransformProperties for PlainEventStream where T: Events, INP: Stream>, { fn query_transform_properties(&self) -> TransformProperties { todo!() } } impl EventStreamTrait for PlainEventStream where T: Events, INP: Stream> + Send, { }