use std::cmp::Ordering;
use std::marker::PhantomData;
use compare::Compare;
use futures::stream::BoxStream;
use crate::stream_more::peeked::Peeked;
pub(crate) struct HeapEntry<'a, D> {
pub(crate) peeked: Peeked<D>,
pub(crate) stream: BoxStream<'a, D>,
pub(crate) id: String,
}
impl<'a, D> HeapEntry<'a, D> {
pub fn new(stream: BoxStream<'a, D>) -> Self {
Self {
peeked: Peeked::No,
stream,
id: "".to_string(),
}
}
pub fn with_id(mut self, id: impl ToString) -> Self {
self.id = id.to_string();
self
}
}
pub struct HeapEntryCmp<D, C: Compare<D>> {
pub cmp: C,
_p: PhantomData<D>,
}
impl<D, C: Compare<D>> HeapEntryCmp<D, C> {
pub fn new(cmp: C) -> Self {
Self { cmp, _p: PhantomData }
}
}
impl<D, C: Compare<D>> Compare<Peeked<D>> for HeapEntryCmp<D, C> {
fn compare(&self, l: &Peeked<D>, r: &Peeked<D>) -> Ordering {
match (l, &r) {
(Peeked::No, Peeked::No) => Ordering::Equal,
(Peeked::No, Peeked::Yes(_)) => Ordering::Greater,
(Peeked::Yes(_), Peeked::No) => Ordering::Less,
(Peeked::Yes(a), Peeked::Yes(b)) => self.cmp.compare(a, b),
}
}
}
impl<'a, D, C: Compare<D>> Compare<HeapEntry<'a, D>> for HeapEntryCmp<D, C> {
fn compare(&self, l: &HeapEntry<D>, r: &HeapEntry<D>) -> Ordering {
self.compare(&l.peeked, &r.peeked)
}
}