1use crate::pull::{FusedPull, Pull, PullStep, fuse_self};
2use crate::{No, Yes};
3
4#[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> {}