avalanche_types/choices/
test_decidable.rs1use crate::{
3 choices::{decidable::Decidable, status::Status},
4 errors::{Error, Result},
5 ids::Id,
6};
7
8#[derive(Clone, Debug)]
9pub struct TestDecidable {
10 pub id: Id,
11
12 pub status: Box<Status>,
18
19 pub accept_result: Result<()>,
20 pub reject_result: Result<()>,
21}
22
23impl Default for TestDecidable {
24 fn default() -> Self {
25 Self {
26 id: Id::empty(),
27
28 status: Box::new(Status::Processing),
29
30 accept_result: Ok(()),
31 reject_result: Ok(()),
32 }
33 }
34}
35
36impl TestDecidable {
37 pub fn new(id: Id, status: Status) -> Self {
38 Self {
39 id,
40 status: Box::new(status),
41 accept_result: Ok(()),
42 reject_result: Ok(()),
43 }
44 }
45
46 pub fn set_accept_result(&mut self, rs: Result<()>) {
47 self.accept_result = rs;
48 }
49
50 pub fn set_reject_result(&mut self, rs: Result<()>) {
51 self.reject_result = rs;
52 }
53
54 pub fn create_decidable(
55 id: Id,
56 status: Status,
57 accept_result: Result<()>,
58 reject_result: Result<()>,
59 ) -> impl Decidable {
60 Self {
61 id,
62 status: Box::new(status),
63 accept_result,
64 reject_result,
65 }
66 }
67}
68
69impl Decidable for TestDecidable {
70 fn id(&self) -> Id {
71 self.id
72 }
73
74 fn status(&self) -> Status {
75 Status::from(self.status.as_str())
76 }
77
78 fn accept(&mut self) -> Result<()> {
79 let status = self.status.as_ref();
80 if matches!(status, Status::Unknown(_) | Status::Rejected) {
81 return Err(Error::Other {
82 message: format!(
83 "invalid state transaction from {} to {}",
84 status,
85 Status::Accepted
86 ),
87 retryable: false,
88 });
89 }
90 if self.accept_result.is_ok() {
91 self.status = Box::new(Status::Accepted);
92 }
93
94 self.accept_result.clone()
95 }
96
97 fn reject(&mut self) -> Result<()> {
98 let status = self.status.as_ref();
99 if matches!(status, Status::Unknown(_) | Status::Accepted) {
100 return Err(Error::Other {
101 message: format!(
102 "invalid state transaction from {} to {}",
103 status,
104 Status::Rejected
105 ),
106 retryable: false,
107 });
108 }
109 if self.reject_result.is_ok() {
110 self.status = Box::new(Status::Rejected);
111 }
112
113 self.reject_result.clone()
114 }
115}
116
117#[test]
119fn test_decidable() {
120 let id = Id::from_slice(&[1, 2, 3]);
121
122 let mut decidable = TestDecidable::create_decidable(id, Status::Processing, Ok(()), Ok(()));
123 assert_eq!(decidable.id(), id);
124 assert_eq!(decidable.status(), Status::Processing);
125 assert!(decidable.accept().is_ok());
126 assert_eq!(decidable.status(), Status::Accepted);
127
128 let mut decidable = TestDecidable::create_decidable(id, Status::Processing, Ok(()), Ok(()));
129 assert_eq!(decidable.id(), id);
130 assert_eq!(decidable.status(), Status::Processing);
131 assert!(decidable.reject().is_ok());
132 assert_eq!(decidable.status(), Status::Rejected);
133
134 let mut decidable = TestDecidable::new(id, Status::Processing);
135 decidable.set_accept_result(Err(Error::Other {
136 message: "test error".to_string(),
137 retryable: false,
138 }));
139 assert_eq!(decidable.id(), id);
140 assert_eq!(decidable.status(), Status::Processing);
141 assert!(decidable.accept().is_err());
142 assert_eq!(decidable.status(), Status::Processing);
143
144 let mut decidable = TestDecidable::create_decidable(
145 id,
146 Status::Processing,
147 Ok(()),
148 Err(Error::Other {
149 message: "test error".to_string(),
150 retryable: false,
151 }),
152 );
153 assert_eq!(decidable.id(), id);
154 assert_eq!(decidable.status(), Status::Processing);
155 assert!(decidable.reject().is_err());
156 assert_eq!(decidable.status(), Status::Processing);
157}