1use server::{AsScalar, FromScalar};
5
6#[derive(Debug, Default, thiserror::Error, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
7pub enum NavigationError {
8 #[default]
9 #[error("Internal error")]
10 InternalError,
11
12 #[error("Request buffer is too small for the response")]
13 RequestBufferTooSmall,
14
15 #[error("An other PID tried to navigate there at the same time (PID={0})")]
16 ConcurrentNavigationRequest(xous::PID),
17
18 #[error("Couldn't find an running app with the given AppId")]
19 AppIdNotFound,
20
21 #[error("No pending navigation request")]
22 NoNavigationRequest,
23
24 #[error("Modal app exited unexpectedly")]
25 ModalExited,
26
27 #[error("The screen is locked")]
28 Locked,
29
30 #[error("The navigation was cancelled by the system")]
31 CanceledBySystem,
32
33 #[error("The navigation was cancelled by the user")]
34 CanceledByUser,
35}
36
37impl AsScalar<3> for NavigationError {
38 fn as_scalar(&self) -> [u32; 3] {
39 match self {
40 NavigationError::InternalError => [1, 0, 0],
41 NavigationError::RequestBufferTooSmall => [2, 0, 0],
42 NavigationError::ConcurrentNavigationRequest(pid) => [3, pid.get() as u32, 0],
43 NavigationError::AppIdNotFound => [4, 0, 0],
44 NavigationError::NoNavigationRequest => [5, 0, 0],
45 NavigationError::ModalExited => [6, 0, 0],
46 NavigationError::Locked => [7, 0, 0],
47 NavigationError::CanceledBySystem => [8, 0, 0],
48 NavigationError::CanceledByUser => [9, 0, 0],
49 }
50 }
51}
52
53impl FromScalar<3> for NavigationError {
54 fn from_scalar([kind, arg, _]: [u32; 3]) -> Self {
55 match kind {
56 1 => NavigationError::InternalError,
57 2 => NavigationError::RequestBufferTooSmall,
58 3 => u8::try_from(arg)
59 .ok()
60 .and_then(xous::PID::new)
61 .map(NavigationError::ConcurrentNavigationRequest)
62 .unwrap_or(NavigationError::InternalError),
63 4 => NavigationError::AppIdNotFound,
64 5 => NavigationError::NoNavigationRequest,
65 6 => NavigationError::ModalExited,
66 7 => NavigationError::Locked,
67 8 => NavigationError::CanceledBySystem,
68 9 => NavigationError::CanceledByUser,
69 _ => NavigationError::InternalError,
70 }
71 }
72}
73
74#[derive(Debug, thiserror::Error, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
75pub enum GuiServerError {
76 #[error("Unknown internal error")]
77 InternalError,
78
79 #[error("OS error: {:?}", xous::Error::from_usize(*.0))]
80 XousError(usize),
81
82 #[error("navigation error: {0:?}")]
83 Navigation(NavigationError),
84
85 #[error("Cannot close an essential app")]
86 CannotCloseEssentialApp,
87
88 #[error("No app window is registered for that PID")]
89 AppNotFound,
90
91 #[error("The app is already closing")]
92 AppAlreadyClosing,
93}
94
95impl From<xous::Error> for GuiServerError {
96 fn from(e: xous::Error) -> Self { GuiServerError::XousError(e.to_usize()) }
97}
98
99impl AsScalar<3> for GuiServerError {
100 fn as_scalar(&self) -> [u32; 3] {
101 match self {
102 GuiServerError::InternalError => [1, 0, 0],
103 GuiServerError::XousError(e) => [2, *e as u32, 0],
104 GuiServerError::Navigation(e) => {
105 let [kind, arg0, _] = e.as_scalar();
106 [3, kind, arg0]
107 }
108 GuiServerError::CannotCloseEssentialApp => [4, 0, 0],
109 GuiServerError::AppNotFound => [5, 0, 0],
110 GuiServerError::AppAlreadyClosing => [6, 0, 0],
111 }
112 }
113}
114
115impl FromScalar<3> for GuiServerError {
116 fn from_scalar([kind, arg0, arg1]: [u32; 3]) -> Self {
117 match kind {
118 1 => GuiServerError::InternalError,
119 2 => GuiServerError::XousError(arg0 as usize),
120 3 => GuiServerError::Navigation(NavigationError::from_scalar([arg0, arg1, 0])),
121 4 => GuiServerError::CannotCloseEssentialApp,
122 5 => GuiServerError::AppNotFound,
123 6 => GuiServerError::AppAlreadyClosing,
124 _ => GuiServerError::InternalError,
125 }
126 }
127}