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