Skip to main content

ace_client/
pending.rs

1// region: Imports
2
3use ace_sim::clock::{Duration, Instant};
4
5// endregion: Imports
6
7// region: P2 State
8
9/// Tracks which timeout phase a pending request is in.
10#[derive(Debug, Clone, PartialEq, Eq)]
11pub enum P2State {
12    /// Waiting for initial response within P2 timeout.
13    Waiting,
14    /// An 0x78 Response Pending was received - now waiting within P2* timeout.
15    Extended,
16}
17
18// endregion: P2 State
19
20// region: Pending Request
21
22/// A request that has been sent and is waiting a response.
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct PendingRequest {
25    /// The request SID byte - used to match incoming responses.
26    pub sid: u8,
27
28    /// The time at which this request was sent.
29    pub sent_at: Instant,
30
31    /// The deadline by which a response must arrive.
32    pub deadline: Instant,
33
34    /// Current timeout phase.
35    pub p2_state: P2State,
36}
37
38impl PendingRequest {
39    pub fn new(sid: u8, sent_at: Instant, p2_timeout: Duration) -> Self {
40        Self {
41            sid,
42            sent_at,
43            deadline: sent_at + p2_timeout,
44            p2_state: P2State::Waiting,
45        }
46    }
47
48    /// Returns true if the deadline has passed.
49    pub fn is_expired(&self, now: Instant) -> bool {
50        now > self.deadline
51    }
52
53    /// Transitions to the extended P2* timeout after receiving 0x78.
54    pub fn extend(&mut self, now: Instant, p2_extended_timeout: Duration) {
55        self.deadline = now + p2_extended_timeout;
56        self.p2_state = P2State::Extended;
57    }
58}
59
60// endregion: Pending Request