somen/stream/imp/
slice.rs

1use core::convert::Infallible;
2use core::pin::Pin;
3use core::task::{Context, Poll};
4use futures_core::Stream;
5use pin_project_lite::pin_project;
6
7use crate::stream::{Positioned, Rewind};
8
9pin_project! {
10    /// Wraps slices, implements [`TryStream`], [`Positioned`] and [`Rewind`] trait.
11    ///
12    /// [`TryStream`]: futures_core::stream::TryStream
13    #[derive(Clone, Debug, PartialEq, Eq)]
14    pub struct SliceStream<'a, T> {
15        slice: &'a [T],
16        position: usize,
17    }
18}
19
20impl<'a, T: Clone> From<&'a [T]> for SliceStream<'a, T> {
21    #[inline]
22    fn from(slice: &'a [T]) -> Self {
23        Self { slice, position: 0 }
24    }
25}
26impl<'a, T: Clone> SliceStream<'a, T> {
27    /// Creates a new instance.
28    #[inline]
29    pub fn new(slice: &'a [T]) -> Self {
30        Self::from(slice)
31    }
32}
33
34impl<T: Clone> Stream for SliceStream<'_, T> {
35    type Item = Result<T, Infallible>;
36
37    fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
38        let this = self.project();
39        let res = this.slice.get(*this.position);
40        *this.position += 1;
41        Poll::Ready(res.cloned().map(Ok))
42    }
43
44    #[inline]
45    fn size_hint(&self) -> (usize, Option<usize>) {
46        (self.slice.len(), Some(self.slice.len()))
47    }
48}
49
50impl<T: Clone> Positioned for SliceStream<'_, T> {
51    type Locator = usize;
52
53    #[inline]
54    fn position(&self) -> Self::Locator {
55        self.position
56    }
57}
58
59impl<T: Clone> Rewind for SliceStream<'_, T> {
60    type Marker = usize;
61
62    #[inline]
63    fn mark(self: Pin<&mut Self>) -> Result<Self::Marker, Self::Error> {
64        Ok(self.position())
65    }
66
67    #[inline]
68    fn rewind(mut self: Pin<&mut Self>, marker: Self::Marker) -> Result<(), Self::Error> {
69        self.position = marker;
70        Ok(())
71    }
72}