1 // Copyright 2025 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 #![no_std] 44 45 /// Status code for no error. 46 pub const OK: u32 = 0; 47 48 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 49 /// Error type compatible with Pigweed's [pw_status](https://pigweed.dev/pw_status). 50 /// 51 /// For an in depth explanation of the values of the `Error` enum, see 52 /// the [Pigweed status codes documentation](https://pigweed.dev/pw_status/#status-codes). 53 pub 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 72 pub type Result<T> = core::result::Result<T, Error>; 73 74 /// Convert a Result into an status code. 75 pub trait StatusCode { 76 /// Return a pigweed compatible status code. status_code(self) -> u3277 fn status_code(self) -> u32; 78 } 79 80 impl<T> StatusCode for Result<T> { status_code(self) -> u3281 fn status_code(self) -> u32 { 82 match self { 83 Ok(_) => OK, 84 Err(e) => e as u32, 85 } 86 } 87 } 88 89 impl embedded_io::Error for Error { kind(&self) -> embedded_io::ErrorKind90 fn kind(&self) -> embedded_io::ErrorKind { 91 use embedded_io::ErrorKind; 92 match self { 93 Error::Cancelled => ErrorKind::Interrupted, 94 Error::Unknown => ErrorKind::Other, 95 Error::InvalidArgument => ErrorKind::InvalidInput, 96 Error::DeadlineExceeded => ErrorKind::TimedOut, 97 Error::NotFound => ErrorKind::NotFound, 98 Error::AlreadyExists => ErrorKind::AlreadyExists, 99 Error::PermissionDenied => ErrorKind::PermissionDenied, 100 Error::ResourceExhausted => ErrorKind::OutOfMemory, 101 Error::FailedPrecondition => ErrorKind::InvalidInput, 102 Error::Aborted => ErrorKind::Interrupted, 103 Error::OutOfRange => ErrorKind::InvalidInput, 104 Error::Unimplemented => ErrorKind::Unsupported, 105 Error::Internal => ErrorKind::Unsupported, 106 Error::Unavailable => ErrorKind::Other, 107 Error::DataLoss => ErrorKind::Other, 108 Error::Unauthenticated => ErrorKind::Other, 109 } 110 } 111 } 112