Skip to main content

deser_core/stream/
elements.rs

1use alloc::boxed::Box;
2use alloc::collections::VecDeque;
3use alloc::sync::Arc;
4use core::any::{Any, TypeId};
5use core::fmt;
6use core::marker::PhantomData;
7
8use crate::State;
9use crate::de::{DeserializeOwned, OwnedDriver, StreamDeserializer};
10use crate::error::Error;
11use crate::stream::{InputBuffer, Status};
12use crate::sync::Mutex;
13
14/// The queue elements of [`Streamed`](super::Streamed) are handed out through.
15struct Queue {
16    type_id: TypeId,
17    elements: Mutex<VecDeque<Box<dyn Any + Send>>>,
18}
19
20impl Queue {
21    fn pop(&self) -> Option<Box<dyn Any + Send>> {
22        self.elements.lock().pop_front()
23    }
24}
25
26/// The queue registered in the state of a value whose elements are handed
27/// out (see [`ElementReader`]).
28#[derive(Clone, Default)]
29struct ElementQueue(Option<Arc<Queue>>);
30
31impl fmt::Debug for ElementQueue {
32    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33        f.debug_struct("ElementQueue").finish_non_exhaustive()
34    }
35}
36
37/// Hands out a complete element if the value is read by an
38/// [`ElementReader`] which hands out elements of its type.
39///
40/// Returns the element back if it's not handed out.
41pub(crate) fn hand_out<T: Send + 'static>(value: T, state: &State) -> Result<(), T> {
42    match state.get::<ElementQueue>() {
43        Some(ElementQueue(Some(queue))) if queue.type_id == TypeId::of::<T>() => {
44            queue.elements.lock().push_back(Box::new(value));
45            Ok(())
46        }
47        _ => Err(value),
48    }
49}
50
51/// A part of a value that is read with the elements of its
52/// [`Streamed`](super::Streamed) sequence handed out.
53///
54/// Such a value is read in parts: first the elements, then the rest of the
55/// value.  This is the result of [`ElementReader::poll`] (and of
56/// `Reader::read_next` of `deser::io`).
57#[derive(Debug, Clone, PartialEq, Eq)]
58pub enum Part<E, T> {
59    /// An element of the [`Streamed`](super::Streamed) sequence of the value.
60    Element(E),
61    /// The value is complete (without the elements that were handed out).
62    Done(T),
63}
64
65/// The state of an [`ElementReader`], see [`ElementReader::poll`].
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub enum ElementStatus<E, T> {
68    /// An element or the value is ready.
69    Ready(Part<E, T>),
70    /// More input is needed.
71    NeedInput,
72    /// There are no more values.
73    End,
74}
75
76/// Reads a value and hands out the elements of its [`Streamed`](super::Streamed) sequence
77/// without doing IO.
78///
79/// This reads the value from an [`InputBuffer`] which is filled by the
80/// caller.  `Reader::read_next` of `deser::io` and adapters for other
81/// kinds of IO (for instance async runtimes) use this.  `T` is the
82/// type of the value, `E` the type of the elements of the [`Streamed`](super::Streamed)
83/// sequence which are handed out.
84///
85/// Elements are handed out before more input is needed, so an element is
86/// available as soon as its last byte was read (if the stream
87/// deserializer supports [`StreamDeserializer::feed`], otherwise once the
88/// value is complete).
89pub struct ElementReader<T, E> {
90    queue: Arc<Queue>,
91    // the value that is deserialized while its input arrives
92    driver: Option<OwnedDriver<'static, T>>,
93    // the complete value, handed out after the elements
94    value: Option<T>,
95    _marker: PhantomData<fn() -> E>,
96}
97
98impl<T: DeserializeOwned + 'static, E: Send + 'static> Default for ElementReader<T, E> {
99    fn default() -> ElementReader<T, E> {
100        ElementReader::new()
101    }
102}
103
104impl<T: DeserializeOwned + 'static, E: Send + 'static> ElementReader<T, E> {
105    /// Creates a reader for a value.
106    pub fn new() -> ElementReader<T, E> {
107        ElementReader {
108            queue: Arc::new(Queue {
109                type_id: TypeId::of::<E>(),
110                elements: Mutex::default(),
111            }),
112            driver: None,
113            value: None,
114            _marker: PhantomData,
115        }
116    }
117
118    /// Returns `true` if a value is being read.
119    ///
120    /// This is `false` before the first call and after the value was
121    /// handed out.
122    pub fn is_reading(&self) -> bool {
123        self.driver.is_some() || self.value.is_some()
124    }
125
126    /// Returns the next element or the value.
127    ///
128    /// Once the value is ready ([`Part::Done`]) the reader is done, the next
129    /// call starts with the next value.
130    pub fn poll<D: StreamDeserializer>(
131        &mut self,
132        buffer: &mut InputBuffer<D>,
133    ) -> Result<ElementStatus<E, T>, Error> {
134        loop {
135            if let Some(element) = self.queue.pop() {
136                let element = *element.downcast::<E>().expect("elements are of type E");
137                return Ok(ElementStatus::Ready(Part::Element(element)));
138            }
139            if let Some(value) = self.value.take() {
140                return Ok(ElementStatus::Ready(Part::Done(value)));
141            }
142
143            let register = ElementQueue(Some(self.queue.clone()));
144            if !buffer.supports_feed() {
145                match buffer.poll()? {
146                    Status::Ready => {
147                        self.value = Some(buffer.deserialize_with(|driver| {
148                            *driver.state_mut().get_mut::<ElementQueue>() = register;
149                        })?);
150                    }
151                    Status::NeedInput => return Ok(ElementStatus::NeedInput),
152                    Status::End => return Ok(ElementStatus::End),
153                }
154                continue;
155            }
156
157            let driver = self.driver.get_or_insert_with(|| {
158                let mut driver = OwnedDriver::new();
159                driver.with(|driver| *driver.state_mut().get_mut::<ElementQueue>() = register);
160                driver
161            });
162            match driver.with(|driver| buffer.feed(driver)) {
163                Ok(Status::Ready) => {
164                    self.value = Some(self.driver.take().unwrap().finish()?);
165                }
166                // elements that were completed are handed out first
167                Ok(Status::NeedInput) => {
168                    if self.queue.elements.lock().is_empty() {
169                        return Ok(ElementStatus::NeedInput);
170                    }
171                }
172                Ok(Status::End) => {
173                    self.driver = None;
174                    return Ok(ElementStatus::End);
175                }
176                Err(err) => {
177                    self.driver = None;
178                    return Err(err);
179                }
180            }
181        }
182    }
183}