use std::task::Poll;
use serde::de::DeserializeOwned;
use super::{ConsumerConfig, Decoder};
use crate::Result;
pub struct Consumer<T> {
track: moq_net::track::Subscriber,
group: Option<moq_net::group::Consumer>,
decoder: Decoder<T>,
frames_read: usize,
}
impl<T: DeserializeOwned> Consumer<T> {
pub fn new(track: moq_net::track::Subscriber, config: ConsumerConfig) -> Self {
Self {
track,
group: None,
decoder: Decoder::new(config),
frames_read: 0,
}
}
pub async fn next(&mut self) -> Result<Option<T>>
where
T: Unpin,
{
kio::wait(|waiter| self.poll_next(waiter)).await
}
pub fn poll_next(&mut self, waiter: &kio::Waiter) -> Poll<Result<Option<T>>> {
let track_finished = loop {
match self.track.poll_next_group(waiter)? {
Poll::Ready(Some(group)) => {
self.group = Some(group);
self.frames_read = 0;
}
Poll::Ready(None) => break true,
Poll::Pending => break false,
}
};
let mut advanced = false;
let mut group_pending = false;
while let Some(group) = &mut self.group {
match group.poll_read_frame(waiter)? {
Poll::Ready(Some(frame)) => {
self.apply(&frame.payload)?;
advanced = true;
}
Poll::Ready(None) => {
self.group = None;
break;
}
Poll::Pending => {
group_pending = true;
break;
}
}
}
if advanced {
return Poll::Ready(Ok(self.decoder.decode()?));
}
if group_pending {
return Poll::Pending;
}
if track_finished {
Poll::Ready(Ok(None))
} else {
Poll::Pending
}
}
fn apply(&mut self, payload: &[u8]) -> Result<()> {
match self.frames_read {
0 => self.decoder.snapshot(payload)?,
_ => self.decoder.delta(payload)?,
}
self.frames_read += 1;
Ok(())
}
}