1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3pub enum FetchState {
4 Idle,
5 Pending,
6 Receiving,
7 Done,
8}
9
10#[derive(Debug, thiserror::Error, PartialEq, Eq)]
11pub enum FetchError {
12 #[error("invalid transition from {from:?} on event {event}")]
13 InvalidTransition { from: FetchState, event: String },
14}
15
16pub struct FetchStateMachine {
19 state: FetchState,
20}
21
22impl Default for FetchStateMachine {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl FetchStateMachine {
29 pub fn new() -> Self {
30 Self { state: FetchState::Idle }
31 }
32
33 pub fn state(&self) -> FetchState {
34 self.state
35 }
36
37 pub fn on_fetch_sent(&mut self) -> Result<(), FetchError> {
39 if self.state == FetchState::Idle {
40 self.state = FetchState::Pending;
41 Ok(())
42 } else {
43 Err(FetchError::InvalidTransition {
44 from: self.state,
45 event: "on_fetch_sent".to_string(),
46 })
47 }
48 }
49
50 pub fn on_fetch_ok(&mut self) -> Result<(), FetchError> {
52 if self.state == FetchState::Pending {
53 self.state = FetchState::Receiving;
54 Ok(())
55 } else {
56 Err(FetchError::InvalidTransition {
57 from: self.state,
58 event: "on_fetch_ok".to_string(),
59 })
60 }
61 }
62
63 pub fn on_fetch_error(&mut self) -> Result<(), FetchError> {
65 if self.state == FetchState::Pending {
66 self.state = FetchState::Done;
67 Ok(())
68 } else {
69 Err(FetchError::InvalidTransition {
70 from: self.state,
71 event: "on_fetch_error".to_string(),
72 })
73 }
74 }
75
76 pub fn on_fetch_cancel(&mut self) -> Result<(), FetchError> {
78 if self.state == FetchState::Pending || self.state == FetchState::Receiving {
79 self.state = FetchState::Done;
80 Ok(())
81 } else {
82 Err(FetchError::InvalidTransition {
83 from: self.state,
84 event: "on_fetch_cancel".to_string(),
85 })
86 }
87 }
88
89 pub fn on_stream_fin(&mut self) -> Result<(), FetchError> {
91 if self.state == FetchState::Receiving {
92 self.state = FetchState::Done;
93 Ok(())
94 } else {
95 Err(FetchError::InvalidTransition {
96 from: self.state,
97 event: "on_stream_fin".to_string(),
98 })
99 }
100 }
101
102 pub fn on_stream_reset(&mut self) -> Result<(), FetchError> {
104 if self.state == FetchState::Receiving {
105 self.state = FetchState::Done;
106 Ok(())
107 } else {
108 Err(FetchError::InvalidTransition {
109 from: self.state,
110 event: "on_stream_reset".to_string(),
111 })
112 }
113 }
114}