use super::{change::ChangeReader, *};
use crate::{error::Closed, IntoReader};
pub struct EventualReader<T> {
change: ChangeReader<T>,
prev: Option<Result<T, Closed>>,
}
impl<T> IntoReader for EventualReader<T>
where
T: Value,
{
type Output = T;
fn into_reader(self) -> EventualReader<Self::Output> {
self
}
}
pub struct Next<'a, T> {
eventual: &'a mut EventualReader<T>,
}
impl<'a, T> Future for Next<'a, T>
where
T: Value,
{
type Output = Result<T, Closed>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let update = self.eventual.change.change.poll(&self.eventual.prev, cx);
match update {
None => Poll::Pending,
Some(value) => {
self.eventual.prev = Some(value.clone());
Poll::Ready(value)
}
}
}
}
impl<T> EventualReader<T>
where
T: Value,
{
pub fn next(&mut self) -> Next<T> {
Next { eventual: self }
}
pub(crate) fn new(state: Arc<SharedState<T>>) -> Self {
let change = state.subscribe();
EventualReader { change, prev: None }
}
pub(crate) fn force_dirty(&mut self) {
self.prev = None;
self.change.unsubscribe_from.notify_one(&self.change.change);
}
}
impl<T> Clone for EventualReader<T>
where
T: Value,
{
fn clone(&self) -> Self {
Self {
prev: self.prev.clone(),
change: self.change.unsubscribe_from.clone().subscribe(),
}
}
}