opentitanlib/test_utils/
status.rs

1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4use serde::{Deserialize, Serialize};
5use std::convert::TryFrom;
6use thiserror::Error;
7
8#[derive(Clone, Debug, Error, Serialize, Deserialize, PartialEq, Eq)]
9pub enum Status {
10    #[error("Not an error ({0})!")]
11    Ok(u32),
12    #[error("Cancelled (module={0} line={1})")]
13    Cancelled(String, u32),
14    #[error("Unknown (module={0} line={1})")]
15    Unknown(String, u32),
16    #[error("Invalid Argument (module={0} line={1})")]
17    InvalidArgument(String, u32),
18    #[error("Deadline Exceeded (module={0} line={1})")]
19    DeadlineExceeded(String, u32),
20    #[error("Not Found (module={0} line={1})")]
21    NotFound(String, u32),
22    #[error("Already Exists (module={0} line={1})")]
23    AlreadyExists(String, u32),
24    #[error("Permission Denied (module={0} line={1})")]
25    PermissionDenied(String, u32),
26    #[error("Resource Exhausted (module={0} line={1})")]
27    ResourceExhausted(String, u32),
28    #[error("Failed Precondition (module={0} line={1})")]
29    FailedPrecondition(String, u32),
30    #[error("Aborted (module={0} line={1})")]
31    Aborted(String, u32),
32    #[error("Out Of Range (module={0} line={1})")]
33    OutOfRange(String, u32),
34    #[error("Unimplemented (module={0} line={1})")]
35    Unimplemented(String, u32),
36    #[error("Internal (module={0} line={1})")]
37    Internal(String, u32),
38    #[error("Unavailable (module={0} line={1})")]
39    Unavailable(String, u32),
40    #[error("Data Loss (module={0} line={1})")]
41    DataLoss(String, u32),
42    #[error("Unauthenticated (module={0} line={1})")]
43    Unauthenticated(String, u32),
44}
45
46#[allow(non_camel_case_types)]
47pub type status_t = Status;
48
49macro_rules! ok_status_to_integer {
50    () => { };
51
52    ($t:ty, $($ts:ty),* $(,)?) => {
53        impl TryFrom<Status> for $t {
54            type Error = Status;
55            fn try_from(value: Status) -> Result<Self, Self::Error> {
56                match value {
57                    Status::Ok(v) => Ok(v as $t),
58                    _ => Err(value),
59                }
60            }
61        }
62        ok_status_to_integer!($($ts,)*);
63    };
64}
65
66// Facilitate easy conversion of Status::Ok(_) to integer types.
67ok_status_to_integer!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
68
69#[cfg(test)]
70mod test {
71    use super::*;
72    use anyhow::Result;
73
74    #[test]
75    fn test_convert_ok() -> Result<()> {
76        let status = Status::Ok(123);
77        assert_eq!(123, i32::try_from(status)?);
78        Ok(())
79    }
80
81    #[test]
82    fn test_convert_err() -> Result<()> {
83        let status = Status::Cancelled("foo".into(), 123);
84        assert!(u32::try_from(status).is_err());
85        Ok(())
86    }
87}