1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10#[repr(i32)]
11pub enum UIMessageCode {
12 BreakOnUserRequest = 1,
14 BreakOnBreakpoint = 2,
16 BreakOnRunTimeError = 3,
18 Trace = 4,
20 TerminatingExecution = 5,
22 AbortingExecution = 6,
24 KillingExecutionThreads = 7,
26 EndExecution = 8,
28 ShutDownComplete = 9,
30 StartExecution = 10,
32 ProgressPercent = 11,
34 ProgressText = 12,
36 StartInteractiveExecution = 13,
38 EndInteractiveExecution = 14,
40 TerminatingInteractiveExecution = 15,
42 TerminationCanceled = 16,
44 ResumeFromBreak = 17,
46 StartFileExecution = 18,
48 EndFileExecution = 19,
50 ShutDownCanceled = 20,
52 LocalizationSettingChanged = 21,
54 OpenWindows = 22,
56 TileWindows = 23,
58 CascadeWindows = 24,
60 ReportChanged = 25,
62 CloseWindows = 26,
64 RefreshWindows = 27,
66 ClientFileChanged = 28,
68 DisplayReport = 29,
70 ModelStateInitializing = 30,
72 ModelStateWaiting = 31,
74 ModelStateIdentified = 32,
76 ModelStateBeginTesting = 33,
78 ModelStateTestingComplete = 34,
80 ModelStatePostProcessingComplete = 35,
82 ModelStateEnabledStateSet = 36,
84 ReportLocationChanged = 37,
86 GotoLocation = 38,
88 PushUndoItem = 39,
90 OutputMessages = 40,
92 TypePaletteFileListChanged = 41,
94 NonTerminatableThreadsArePreventingTermination = 42,
96 ModelStatePostProcessing = 43,
98 ReportCollectionChanged = 44,
100 RuntimeError = 45,
102}
103
104impl UIMessageCode {
105 pub const ALL: [Self; 45] = [
107 Self::BreakOnUserRequest,
108 Self::BreakOnBreakpoint,
109 Self::BreakOnRunTimeError,
110 Self::Trace,
111 Self::TerminatingExecution,
112 Self::AbortingExecution,
113 Self::KillingExecutionThreads,
114 Self::EndExecution,
115 Self::ShutDownComplete,
116 Self::StartExecution,
117 Self::ProgressPercent,
118 Self::ProgressText,
119 Self::StartInteractiveExecution,
120 Self::EndInteractiveExecution,
121 Self::TerminatingInteractiveExecution,
122 Self::TerminationCanceled,
123 Self::ResumeFromBreak,
124 Self::StartFileExecution,
125 Self::EndFileExecution,
126 Self::ShutDownCanceled,
127 Self::LocalizationSettingChanged,
128 Self::OpenWindows,
129 Self::TileWindows,
130 Self::CascadeWindows,
131 Self::ReportChanged,
132 Self::CloseWindows,
133 Self::RefreshWindows,
134 Self::ClientFileChanged,
135 Self::DisplayReport,
136 Self::ModelStateInitializing,
137 Self::ModelStateWaiting,
138 Self::ModelStateIdentified,
139 Self::ModelStateBeginTesting,
140 Self::ModelStateTestingComplete,
141 Self::ModelStatePostProcessingComplete,
142 Self::ModelStateEnabledStateSet,
143 Self::ReportLocationChanged,
144 Self::GotoLocation,
145 Self::PushUndoItem,
146 Self::OutputMessages,
147 Self::TypePaletteFileListChanged,
148 Self::NonTerminatableThreadsArePreventingTermination,
149 Self::ModelStatePostProcessing,
150 Self::ReportCollectionChanged,
151 Self::RuntimeError,
152 ];
153
154 pub const USER_MESSAGE_BASE: i32 = 10000;
159
160 #[must_use]
162 pub const fn bits(self) -> i32 {
163 self as i32
164 }
165
166 #[must_use]
168 pub const fn is_user_message(raw: i32) -> bool {
169 raw >= Self::USER_MESSAGE_BASE
170 }
171
172 pub const fn from_bits(raw: i32) -> Result<Self, i32> {
177 Ok(match raw {
178 1 => Self::BreakOnUserRequest,
179 2 => Self::BreakOnBreakpoint,
180 3 => Self::BreakOnRunTimeError,
181 4 => Self::Trace,
182 5 => Self::TerminatingExecution,
183 6 => Self::AbortingExecution,
184 7 => Self::KillingExecutionThreads,
185 8 => Self::EndExecution,
186 9 => Self::ShutDownComplete,
187 10 => Self::StartExecution,
188 11 => Self::ProgressPercent,
189 12 => Self::ProgressText,
190 13 => Self::StartInteractiveExecution,
191 14 => Self::EndInteractiveExecution,
192 15 => Self::TerminatingInteractiveExecution,
193 16 => Self::TerminationCanceled,
194 17 => Self::ResumeFromBreak,
195 18 => Self::StartFileExecution,
196 19 => Self::EndFileExecution,
197 20 => Self::ShutDownCanceled,
198 21 => Self::LocalizationSettingChanged,
199 22 => Self::OpenWindows,
200 23 => Self::TileWindows,
201 24 => Self::CascadeWindows,
202 25 => Self::ReportChanged,
203 26 => Self::CloseWindows,
204 27 => Self::RefreshWindows,
205 28 => Self::ClientFileChanged,
206 29 => Self::DisplayReport,
207 30 => Self::ModelStateInitializing,
208 31 => Self::ModelStateWaiting,
209 32 => Self::ModelStateIdentified,
210 33 => Self::ModelStateBeginTesting,
211 34 => Self::ModelStateTestingComplete,
212 35 => Self::ModelStatePostProcessingComplete,
213 36 => Self::ModelStateEnabledStateSet,
214 37 => Self::ReportLocationChanged,
215 38 => Self::GotoLocation,
216 39 => Self::PushUndoItem,
217 40 => Self::OutputMessages,
218 41 => Self::TypePaletteFileListChanged,
219 42 => Self::NonTerminatableThreadsArePreventingTermination,
220 43 => Self::ModelStatePostProcessing,
221 44 => Self::ReportCollectionChanged,
222 45 => Self::RuntimeError,
223 other => return Err(other),
224 })
225 }
226}
227
228#[cfg(test)]
229mod tests {
230 use super::UIMessageCode;
231
232 #[test]
233 fn every_code_round_trips() {
234 for code in UIMessageCode::ALL {
235 assert_eq!(UIMessageCode::from_bits(code.bits()), Ok(code));
236 }
237 }
238
239 #[test]
240 fn engine_codes_sit_below_the_user_range() {
241 for code in UIMessageCode::ALL {
244 assert!(
245 !UIMessageCode::is_user_message(code.bits()),
246 "{code:?} collides with the user range"
247 );
248 }
249 }
250
251 #[test]
252 fn a_sequence_posted_code_is_recognized() {
253 assert!(UIMessageCode::is_user_message(
254 UIMessageCode::USER_MESSAGE_BASE
255 ));
256 assert!(UIMessageCode::is_user_message(
257 UIMessageCode::USER_MESSAGE_BASE + 1
258 ));
259 assert_eq!(
260 UIMessageCode::from_bits(UIMessageCode::USER_MESSAGE_BASE + 1),
261 Err(10001)
262 );
263 }
264
265 #[test]
266 fn shutdown_complete_keeps_the_value_the_watchdog_relies_on() {
267 assert_eq!(UIMessageCode::ShutDownComplete.bits(), 9);
270 }
271}