xref: /aosp_15_r20/external/pigweed/pw_status/rust/pw_status.rs (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 //! # pw_status
16 //!
17 //! Rust error types using error codes compatible with Pigweed's
18 //! [pw_status](https://pigweed.dev/pw_status).  In order to keep the interface
19 //! idiomatic for Rust, `PW_STATUS_OK` is omitted from the Error enum and a
20 //! `StatusCode` trait is provided to turn a `Result` into a canonical
21 //! status code.
22 //!
23 //! For an in depth explanation of the values of the `Error` enum, see
24 //! the [Pigweed status codes documentation](https://pigweed.dev/pw_status/#status-codes).
25 //!
26 //! # Example
27 //!
28 //! ```
29 //! use pw_status::{Error, Result};
30 //!
31 //! fn div(numerator: u32, denominator: u32) -> Result<u32> {
32 //!     if denominator == 0 {
33 //!         Err(Error::FailedPrecondition)
34 //!     } else {
35 //!         Ok(numerator / denominator)
36 //!     }
37 //! }
38 //!
39 //! assert_eq!(div(4, 2), Ok(2));
40 //! assert_eq!(div(4, 0), Err(Error::FailedPrecondition));
41 //! ```
42 
43 #![cfg_attr(not(feature = "std"), no_std)]
44 
45 /// Status code for no error.
46 pub const OK: u32 = 0;
47 
48 #[cfg_attr(feature = "std", derive(Debug))]
49 #[derive(Clone, Copy, Eq, PartialEq)]
50 /// Error type compatible with Pigweed's [pw_status](https://pigweed.dev/pw_status).
51 ///
52 /// For an in depth explanation of the values of the `Error` enum, see
53 /// the [Pigweed status codes documentation](https://pigweed.dev/pw_status/#status-codes).
54 pub enum Error {
55     Cancelled = 1,
56     Unknown = 2,
57     InvalidArgument = 3,
58     DeadlineExceeded = 4,
59     NotFound = 5,
60     AlreadyExists = 6,
61     PermissionDenied = 7,
62     ResourceExhausted = 8,
63     FailedPrecondition = 9,
64     Aborted = 10,
65     OutOfRange = 11,
66     Unimplemented = 12,
67     Internal = 13,
68     Unavailable = 14,
69     DataLoss = 15,
70     Unauthenticated = 16,
71 }
72 
73 pub type Result<T> = core::result::Result<T, Error>;
74 
75 /// Convert a Result into an status code.
76 pub trait StatusCode {
77     /// Return a pigweed compatible status code.
status_code(self) -> u3278     fn status_code(self) -> u32;
79 }
80 
81 impl<T> StatusCode for Result<T> {
status_code(self) -> u3282     fn status_code(self) -> u32 {
83         match self {
84             Ok(_) => OK,
85             Err(e) => e as u32,
86         }
87     }
88 }
89 
90 #[cfg(test)]
91 mod tests {
92     use super::*;
93     #[test]
test_status_code()94     fn test_status_code() {
95         assert_eq!(Result::Ok(()).status_code(), 0);
96         assert_eq!(Result::<()>::Err(Error::Cancelled).status_code(), 1);
97         assert_eq!(Result::<()>::Err(Error::Unknown).status_code(), 2);
98         assert_eq!(Result::<()>::Err(Error::InvalidArgument).status_code(), 3);
99         assert_eq!(Result::<()>::Err(Error::DeadlineExceeded).status_code(), 4);
100         assert_eq!(Result::<()>::Err(Error::NotFound).status_code(), 5);
101         assert_eq!(Result::<()>::Err(Error::AlreadyExists).status_code(), 6);
102         assert_eq!(Result::<()>::Err(Error::PermissionDenied).status_code(), 7);
103         assert_eq!(Result::<()>::Err(Error::ResourceExhausted).status_code(), 8);
104         assert_eq!(
105             Result::<()>::Err(Error::FailedPrecondition).status_code(),
106             9
107         );
108         assert_eq!(Result::<()>::Err(Error::Aborted).status_code(), 10);
109         assert_eq!(Result::<()>::Err(Error::OutOfRange).status_code(), 11);
110         assert_eq!(Result::<()>::Err(Error::Unimplemented).status_code(), 12);
111         assert_eq!(Result::<()>::Err(Error::Internal).status_code(), 13);
112         assert_eq!(Result::<()>::Err(Error::Unavailable).status_code(), 14);
113         assert_eq!(Result::<()>::Err(Error::DataLoss).status_code(), 15);
114         assert_eq!(Result::<()>::Err(Error::Unauthenticated).status_code(), 16);
115     }
116 }
117