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