use crate::valtron::wake::WakeableStream;
#[derive(Clone)]
pub enum StreamSpread<D, P> {
Pending(P),
Done(D),
}
impl<D: PartialEq, P: PartialEq> PartialEq for StreamSpread<D, P> {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Done(me), Self::Done(them)) => me == them,
(Self::Pending(me), Self::Pending(them)) => me == them,
_ => false,
}
}
}
impl<D: core::fmt::Debug, P: core::fmt::Debug> core::fmt::Display for StreamSpread<D, P> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Pending(p) => write!(f, "Pending({p:?})"),
Self::Done(d) => write!(f, "Next({d:?})"),
}
}
}
impl<D: core::fmt::Debug, P: core::fmt::Debug> core::fmt::Debug for StreamSpread<D, P> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Pending(p) => f.debug_tuple("Pending").field(p).finish(),
Self::Done(d) => f.debug_tuple("Next").field(d).finish(),
}
}
}
#[derive(PartialEq, Clone)]
pub enum Stream<D, P> {
Init,
Ignore,
Delayed(std::time::Duration),
Pending(P),
Next(D),
Wait,
Spread(Vec<StreamSpread<D, P>>),
}
impl<D: core::fmt::Debug, P: core::fmt::Debug> core::fmt::Display for Stream<D, P> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Stream::Init => write!(f, "Init"),
Stream::Ignore => write!(f, "Ignore"),
Stream::Delayed(d) => write!(f, "Delayed({d:?})"),
Stream::Pending(p) => write!(f, "Pending({p:?})"),
Stream::Next(d) => write!(f, "Next({d:?})"),
Stream::Wait => write!(f, "Wait"),
Stream::Spread(items) => write!(f, "Spread({items:?})"),
}
}
}
impl<D: core::fmt::Debug, P: core::fmt::Debug> core::fmt::Debug for Stream<D, P> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Stream::Init => f.write_str("Init"),
Stream::Ignore => f.write_str("Ignore"),
Stream::Delayed(d) => f.debug_tuple("Delayed").field(d).finish(),
Stream::Pending(p) => f.debug_tuple("Pending").field(p).finish(),
Stream::Next(d) => f.debug_tuple("Next").field(d).finish(),
Stream::Wait => f.write_str("Wait"),
Stream::Spread(items) => f.debug_tuple("Spread").field(items).finish(),
}
}
}
pub trait StreamIterator: Iterator<Item = Stream<Self::D, Self::P>> {
type D;
type P;
}
#[derive(Debug)]
pub struct StreamIter<S: StreamIterator>(pub S);
impl<S: StreamIterator> Iterator for StreamIter<S> {
type Item = Stream<S::D, S::P>;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
#[cfg(feature = "multi")]
impl<S> WakeableStream for StreamIter<S>
where
S: StreamIterator,
S::D: Send + 'static,
S::P: Send + 'static,
{
}
#[cfg(not(feature = "multi"))]
impl<S> WakeableStream for StreamIter<S>
where
S: StreamIterator,
S::D: 'static,
S::P: 'static,
{
}
#[cfg(feature = "multi")]
impl<M, D, P> StreamIterator for M
where
M: Iterator<Item = Stream<D, P>> + ?Sized,
D: Send + 'static,
P: Send + 'static,
{
type D = D;
type P = P;
}
#[cfg(not(feature = "multi"))]
impl<M, D, P> StreamIterator for M
where
M: Iterator<Item = Stream<D, P>> + ?Sized,
D: 'static,
P: 'static,
{
type D = D;
type P = P;
}
pub enum ShortCircuit<D, P> {
Continue(Stream<D, P>),
ReturnAndStop(Stream<D, P>),
Stop,
}