nuts/nut/iac/publish/
response.rs1use std::{future::Future, task::Poll};
2
3use crate::nut::Nut;
4
5#[derive(Default)]
6pub(crate) struct ResponseTracker {
7 slots: Vec<SlotState>,
8}
9
10enum SlotState {
11 Available,
12 Occupied,
13 Done,
14}
15
16pub(crate) struct Slot(usize);
17
18#[allow(clippy::single_match)]
19impl ResponseTracker {
20 pub fn allocate(&mut self) -> Slot {
21 for (i, slot) in self.slots.iter_mut().enumerate() {
22 match slot {
23 SlotState::Available => {
24 *slot = SlotState::Occupied;
25 return Slot(i);
26 }
27 _ => {}
28 }
29 }
30 let i = self.slots.len();
31 self.slots.push(SlotState::Occupied);
32 Slot(i)
33 }
34 pub fn done(&mut self, slot: &Slot) {
35 self.slots[slot.0] = SlotState::Done;
36 }
37 fn free(&mut self, index: usize) {
38 self.slots[index] = SlotState::Available;
39 }
40}
41
42pub struct NutsResponse {
43 index: usize,
44}
45
46impl NutsResponse {
47 pub(crate) fn new(slot: &Slot) -> Self {
48 Self { index: slot.0 }
49 }
50}
51
52impl Future for NutsResponse {
53 type Output = ();
54
55 fn poll(
56 self: std::pin::Pin<&mut Self>,
57 _cx: &mut std::task::Context<'_>,
58 ) -> Poll<Self::Output> {
59 Nut::with_response_tracker_mut(|response_tracker| {
60 match response_tracker.slots[self.index] {
61 SlotState::Available => panic!("Corrupted futures State"),
62 SlotState::Occupied => Poll::Pending,
63 SlotState::Done => {
64 response_tracker.free(self.index);
65 Poll::Ready(())
66 }
67 }
68 })
69 }
70}