Skip to main content

dfir_pipes/pull/
once.rs

1use crate::pull::{FusedPull, Pull, PullStep, fuse_self};
2use crate::{No, Yes};
3
4/// A pull that yields a single item.
5#[must_use = "`Pull`s do nothing unless polled"]
6#[derive(Clone, Debug, Default)]
7pub struct Once<Item> {
8    item: Option<Item>,
9}
10
11impl<Item> Once<Item>
12where
13    Self: Pull,
14{
15    pub(crate) const fn new(item: Item) -> Self {
16        Self { item: Some(item) }
17    }
18}
19
20impl<Item> Unpin for Once<Item> {}
21
22impl<Item> Pull for Once<Item> {
23    type Ctx<'ctx> = ();
24
25    type Item = Item;
26    type Meta = ();
27    type CanPend = No;
28    type CanEnd = Yes;
29
30    fn pull(
31        self: core::pin::Pin<&mut Self>,
32        _ctx: &mut Self::Ctx<'_>,
33    ) -> PullStep<Self::Item, Self::Meta, Self::CanPend, Self::CanEnd> {
34        match self.get_mut().item.take() {
35            Some(item) => PullStep::Ready(item, ()),
36            None => PullStep::Ended(Yes),
37        }
38    }
39
40    fn size_hint(&self) -> (usize, Option<usize>) {
41        let n = if self.item.is_some() { 1 } else { 0 };
42        (n, Some(n))
43    }
44
45    fuse_self!();
46}
47
48impl<Item> FusedPull for Once<Item> {}