Skip to main content

dfir_pipes/push/
vec_push.rs

1//! [`VecPush`] terminal push operator that collects items into a `Vec`.
2use alloc::vec::Vec;
3use core::borrow::BorrowMut;
4use core::pin::Pin;
5
6use pin_project_lite::pin_project;
7
8use crate::No;
9use crate::push::{Push, PushStep};
10
11pin_project! {
12    /// Terminal push operator that collects items into a `Vec`.
13    ///
14    /// Uses [`Push::size_hint`] to pre-allocate capacity via [`Vec::reserve`].
15    #[must_use = "`Push`es do nothing unless items are pushed into them"]
16    pub struct VecPush<Buf> {
17        buf: Buf,
18    }
19}
20
21impl<Buf> VecPush<Buf> {
22    /// Creates a new [`VecPush`] writing into the given buffer.
23    pub(crate) const fn new<Item>(buf: Buf) -> Self
24    where
25        Buf: BorrowMut<Vec<Item>>,
26    {
27        Self { buf }
28    }
29}
30
31impl<Buf, Item, Meta> Push<Item, Meta> for VecPush<Buf>
32where
33    Buf: BorrowMut<Vec<Item>>,
34    Meta: Copy,
35{
36    type Ctx<'ctx> = ();
37    type CanPend = No;
38
39    fn poll_ready(self: Pin<&mut Self>, _ctx: &mut Self::Ctx<'_>) -> PushStep<Self::CanPend> {
40        PushStep::Done
41    }
42
43    fn start_send(self: Pin<&mut Self>, item: Item, _meta: Meta) {
44        self.project().buf.borrow_mut().push(item);
45    }
46
47    fn poll_flush(self: Pin<&mut Self>, _ctx: &mut Self::Ctx<'_>) -> PushStep<Self::CanPend> {
48        PushStep::Done
49    }
50
51    fn size_hint(self: Pin<&mut Self>, hint: (usize, Option<usize>)) {
52        self.project().buf.borrow_mut().reserve(hint.0);
53    }
54}