Skip to main content

dfir_rs/scheduled/handoff/
mod.rs

1//! Module for all [`Handoff`]-related items.
2
3pub mod handoff_list;
4mod tee;
5mod vector;
6
7use std::any::Any;
8use std::cell::{RefCell, RefMut};
9use std::rc::Rc;
10
11pub use tee::TeeingHandoff;
12pub use vector::VecHandoff;
13
14/// Trait representing something which we can attempt to give an item to.
15pub trait TryCanReceive<T> {
16    // TODO(mingwei): Isn't used.
17    /// Try to give a value to the handoff, may return an error if full, representing backpressure.
18    fn try_give(&self, item: T) -> Result<T, T>;
19}
20
21/// Trait representing somethign which we can give an item to.
22pub trait CanReceive<T> {
23    // TODO: represent backpressure in this return value.
24    /// Give a value to the handoff.
25    fn give(&self, item: T) -> T;
26}
27
28/// A handle onto the metadata part of a [Handoff], with no element type.
29pub trait HandoffMeta: Any {
30    /// Return if the handoff has no items ready to be read.
31    fn is_empty(&self) -> bool {
32        0 == self.len()
33    }
34
35    /// Return the number of items ready to be read out of the handoff.
36    fn len(&self) -> usize;
37}
38
39impl<H> HandoffMeta for Rc<RefCell<H>>
40where
41    H: HandoffMeta,
42{
43    fn len(&self) -> usize {
44        self.borrow().len()
45    }
46}
47
48/// Trait for handoffs to implement.
49pub trait Handoff: Default + HandoffMeta {
50    /// Inner datastructure type.
51    type Inner;
52
53    /// Take the inner datastructure, similar to [`std::mem::take`].
54    fn take_inner(&self) -> Self::Inner;
55
56    /// Take the inner datastructure by swapping input and output buffers.
57    ///
58    /// For better performance over [`Self::take_inner`].
59    fn borrow_mut_swap(&self) -> RefMut<'_, Self::Inner>;
60
61    /// Borrow a mutable inner to give items to.
62    fn borrow_mut_give(&self) -> RefMut<'_, Self::Inner>;
63
64    /// See [`CanReceive::give`].
65    fn give<T>(&self, item: T) -> T
66    where
67        Self: CanReceive<T>,
68    {
69        <Self as CanReceive<T>>::give(self, item)
70    }
71
72    /// See [`TryCanReceive::try_give`].
73    fn try_give<T>(&self, item: T) -> Result<T, T>
74    where
75        Self: TryCanReceive<T>,
76    {
77        <Self as TryCanReceive<T>>::try_give(self, item)
78    }
79}
80
81/// Wrapper around `IntoIterator` to avoid trait impl conflicts.
82#[repr(transparent)]
83#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
84pub struct Iter<I>(pub I)
85where
86    I: IntoIterator;
87impl<I> IntoIterator for Iter<I>
88where
89    I: IntoIterator,
90{
91    type Item = I::Item;
92    type IntoIter = I::IntoIter;
93
94    fn into_iter(self) -> Self::IntoIter {
95        self.0.into_iter()
96    }
97}