use alloc::boxed::Box;
use alloc::collections::VecDeque;
use alloc::sync::Arc;
use core::any::{Any, TypeId};
use core::fmt;
use core::marker::PhantomData;
use crate::State;
use crate::de::{DeserializeOwned, OwnedDriver, StreamDeserializer};
use crate::error::Error;
use crate::stream::{InputBuffer, Status};
use crate::sync::Mutex;
struct Queue {
type_id: TypeId,
elements: Mutex<VecDeque<Box<dyn Any + Send>>>,
}
impl Queue {
fn pop(&self) -> Option<Box<dyn Any + Send>> {
self.elements.lock().pop_front()
}
}
#[derive(Clone, Default)]
struct ElementQueue(Option<Arc<Queue>>);
impl fmt::Debug for ElementQueue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ElementQueue").finish_non_exhaustive()
}
}
pub(crate) fn hand_out<T: Send + 'static>(value: T, state: &State) -> Result<(), T> {
match state.get::<ElementQueue>() {
Some(ElementQueue(Some(queue))) if queue.type_id == TypeId::of::<T>() => {
queue.elements.lock().push_back(Box::new(value));
Ok(())
}
_ => Err(value),
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Part<E, T> {
Element(E),
Done(T),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ElementStatus<E, T> {
Ready(Part<E, T>),
NeedInput,
End,
}
pub struct ElementReader<T, E> {
queue: Arc<Queue>,
driver: Option<OwnedDriver<'static, T>>,
value: Option<T>,
_marker: PhantomData<fn() -> E>,
}
impl<T: DeserializeOwned + 'static, E: Send + 'static> Default for ElementReader<T, E> {
fn default() -> ElementReader<T, E> {
ElementReader::new()
}
}
impl<T: DeserializeOwned + 'static, E: Send + 'static> ElementReader<T, E> {
pub fn new() -> ElementReader<T, E> {
ElementReader {
queue: Arc::new(Queue {
type_id: TypeId::of::<E>(),
elements: Mutex::default(),
}),
driver: None,
value: None,
_marker: PhantomData,
}
}
pub fn is_reading(&self) -> bool {
self.driver.is_some() || self.value.is_some()
}
pub fn poll<D: StreamDeserializer>(
&mut self,
buffer: &mut InputBuffer<D>,
) -> Result<ElementStatus<E, T>, Error> {
loop {
if let Some(element) = self.queue.pop() {
let element = *element.downcast::<E>().expect("elements are of type E");
return Ok(ElementStatus::Ready(Part::Element(element)));
}
if let Some(value) = self.value.take() {
return Ok(ElementStatus::Ready(Part::Done(value)));
}
let register = ElementQueue(Some(self.queue.clone()));
if !buffer.supports_partial() {
match buffer.poll()? {
Status::Ready => {
self.value = Some(buffer.deserialize_with(|driver| {
*driver.state_mut().get_mut::<ElementQueue>() = register;
})?);
}
Status::NeedInput => return Ok(ElementStatus::NeedInput),
Status::End => return Ok(ElementStatus::End),
}
continue;
}
let driver = self.driver.get_or_insert_with(|| {
let mut driver = OwnedDriver::new();
driver.with(|driver| *driver.state_mut().get_mut::<ElementQueue>() = register);
driver
});
match driver.with(|driver| buffer.drive_partial(driver)) {
Ok(Status::Ready) => {
self.value = Some(self.driver.take().unwrap().finish()?);
}
Ok(Status::NeedInput) => {
if self.queue.elements.lock().is_empty() {
return Ok(ElementStatus::NeedInput);
}
}
Ok(Status::End) => {
self.driver = None;
return Ok(ElementStatus::End);
}
Err(err) => {
self.driver = None;
return Err(err);
}
}
}
}
}