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 /// Helper to cast an instance of `HandoffMeta` to [`Any`]. In general you cannot cast between
31 /// traits, including [`Any`], but this helper method works around that limitation.
32 ///
33 /// For implementors: the body of this method will generally just be `{ self }`.
34 fn any_ref(&self) -> &dyn Any;
35
36 // TODO(justin): more fine-grained info here.
37 /// Return if the handoff is empty.
38 fn is_bottom(&self) -> bool;
39}
40
41impl<H> HandoffMeta for Rc<RefCell<H>>
42where
43 H: HandoffMeta,
44{
45 fn any_ref(&self) -> &dyn Any {
46 self
47 }
48
49 fn is_bottom(&self) -> bool {
50 self.borrow().is_bottom()
51 }
52}
53
54/// Trait for handoffs to implement.
55pub trait Handoff: Default + HandoffMeta {
56 /// Inner datastructure type.
57 type Inner;
58
59 /// Take the inner datastructure, similar to [`std::mem::take`].
60 fn take_inner(&self) -> Self::Inner;
61
62 /// Take the inner datastructure by swapping input and output buffers.
63 ///
64 /// For better performance over [`Self::take_inner`].
65 fn borrow_mut_swap(&self) -> RefMut<Self::Inner>;
66
67 /// See [`CanReceive::give`].
68 fn give<T>(&self, item: T) -> T
69 where
70 Self: CanReceive<T>,
71 {
72 <Self as CanReceive<T>>::give(self, item)
73 }
74
75 /// See [`TryCanReceive::try_give`].
76 fn try_give<T>(&self, item: T) -> Result<T, T>
77 where
78 Self: TryCanReceive<T>,
79 {
80 <Self as TryCanReceive<T>>::try_give(self, item)
81 }
82}
83
84/// Wrapper around `IntoIterator` to avoid trait impl conflicts.
85#[repr(transparent)]
86#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
87pub struct Iter<I>(pub I)
88where
89 I: IntoIterator;
90impl<I> IntoIterator for Iter<I>
91where
92 I: IntoIterator,
93{
94 type Item = I::Item;
95 type IntoIter = I::IntoIter;
96
97 fn into_iter(self) -> Self::IntoIter {
98 self.0.into_iter()
99 }
100}