1#![no_std]
43
44pub const OK: u32 = 0;
46
47#[derive(Clone, Copy, Debug, Eq, PartialEq)]
52#[repr(u32)]
53pub enum Error {
54 Cancelled = 1,
55 Unknown = 2,
56 InvalidArgument = 3,
57 DeadlineExceeded = 4,
58 NotFound = 5,
59 AlreadyExists = 6,
60 PermissionDenied = 7,
61 ResourceExhausted = 8,
62 FailedPrecondition = 9,
63 Aborted = 10,
64 OutOfRange = 11,
65 Unimplemented = 12,
66 Internal = 13,
67 Unavailable = 14,
68 DataLoss = 15,
69 Unauthenticated = 16,
70}
71
72impl TryFrom<u32> for Error {
73 type Error = Self;
74
75 fn try_from(val: u32) -> core::result::Result<Self, Self::Error> {
76 match val {
77 1 => Ok(Error::Cancelled),
78 2 => Ok(Error::Unknown),
79 3 => Ok(Error::InvalidArgument),
80 4 => Ok(Error::DeadlineExceeded),
81 5 => Ok(Error::NotFound),
82 6 => Ok(Error::AlreadyExists),
83 7 => Ok(Error::PermissionDenied),
84 8 => Ok(Error::ResourceExhausted),
85 9 => Ok(Error::FailedPrecondition),
86 10 => Ok(Error::Aborted),
87 11 => Ok(Error::OutOfRange),
88 12 => Ok(Error::Unimplemented),
89 13 => Ok(Error::Internal),
90 14 => Ok(Error::Unavailable),
91 15 => Ok(Error::DataLoss),
92 16 => Ok(Error::Unauthenticated),
93 _ => Err(Error::InvalidArgument),
94 }
95 }
96}
97
98pub type Result<T> = core::result::Result<T, Error>;
99
100pub trait StatusCode {
102 fn status_code(self) -> u32;
104}
105
106impl<T> StatusCode for Result<T> {
107 fn status_code(self) -> u32 {
108 match self {
109 Ok(_) => OK,
110 Err(e) => e as u32,
111 }
112 }
113}
114
115pub fn status_to_result(status: u32) -> Result<()> {
122 if status == OK {
123 Ok(())
124 } else {
125 match Error::try_from(status) {
126 Ok(e) => Err(e),
127 Err(_) => Err(Error::Unknown),
128 }
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135 #[test]
136 fn test_status_code() {
137 assert_eq!(Result::Ok(()).status_code(), 0);
138 assert_eq!(Result::<()>::Err(Error::Cancelled).status_code(), 1);
139 assert_eq!(Result::<()>::Err(Error::Unknown).status_code(), 2);
140 assert_eq!(Result::<()>::Err(Error::InvalidArgument).status_code(), 3);
141 assert_eq!(Result::<()>::Err(Error::DeadlineExceeded).status_code(), 4);
142 assert_eq!(Result::<()>::Err(Error::NotFound).status_code(), 5);
143 assert_eq!(Result::<()>::Err(Error::AlreadyExists).status_code(), 6);
144 assert_eq!(Result::<()>::Err(Error::PermissionDenied).status_code(), 7);
145 assert_eq!(Result::<()>::Err(Error::ResourceExhausted).status_code(), 8);
146 assert_eq!(
147 Result::<()>::Err(Error::FailedPrecondition).status_code(),
148 9
149 );
150 assert_eq!(Result::<()>::Err(Error::Aborted).status_code(), 10);
151 assert_eq!(Result::<()>::Err(Error::OutOfRange).status_code(), 11);
152 assert_eq!(Result::<()>::Err(Error::Unimplemented).status_code(), 12);
153 assert_eq!(Result::<()>::Err(Error::Internal).status_code(), 13);
154 assert_eq!(Result::<()>::Err(Error::Unavailable).status_code(), 14);
155 assert_eq!(Result::<()>::Err(Error::DataLoss).status_code(), 15);
156 assert_eq!(Result::<()>::Err(Error::Unauthenticated).status_code(), 16);
157 }
158
159 #[test]
160 fn test_status_to_result() {
161 assert_eq!(status_to_result(0), Ok(()));
162 assert_eq!(status_to_result(1), Err(Error::Cancelled));
163 assert_eq!(status_to_result(13), Err(Error::Internal));
164 assert_eq!(status_to_result(999), Err(Error::Unknown));
165 }
166}