Skip to main content

scs_sdk/
error.rs

1use core::fmt;
2
3use crate::sys;
4
5pub type SdkResult<T = ()> = Result<T, SdkError>;
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum SdkError {
9    Unsupported,
10    InvalidParameter,
11    AlreadyRegistered,
12    NotFound,
13    UnsupportedType,
14    NotNow,
15    Generic,
16    Unknown(sys::ScsResult),
17}
18
19impl SdkError {
20    /// Converts an SDK result code into a Rust result.
21    ///
22    /// # Errors
23    ///
24    /// Returns the matching error variant for every non-zero SDK result code.
25    pub const fn from_code(code: sys::ScsResult) -> SdkResult {
26        match code {
27            sys::SCS_RESULT_OK => Ok(()),
28            sys::SCS_RESULT_UNSUPPORTED => Err(Self::Unsupported),
29            sys::SCS_RESULT_INVALID_PARAMETER => Err(Self::InvalidParameter),
30            sys::SCS_RESULT_ALREADY_REGISTERED => Err(Self::AlreadyRegistered),
31            sys::SCS_RESULT_NOT_FOUND => Err(Self::NotFound),
32            sys::SCS_RESULT_UNSUPPORTED_TYPE => Err(Self::UnsupportedType),
33            sys::SCS_RESULT_NOT_NOW => Err(Self::NotNow),
34            sys::SCS_RESULT_GENERIC_ERROR => Err(Self::Generic),
35            value => Err(Self::Unknown(value)),
36        }
37    }
38
39    #[must_use]
40    pub const fn code(self) -> sys::ScsResult {
41        match self {
42            Self::Unsupported => sys::SCS_RESULT_UNSUPPORTED,
43            Self::InvalidParameter => sys::SCS_RESULT_INVALID_PARAMETER,
44            Self::AlreadyRegistered => sys::SCS_RESULT_ALREADY_REGISTERED,
45            Self::NotFound => sys::SCS_RESULT_NOT_FOUND,
46            Self::UnsupportedType => sys::SCS_RESULT_UNSUPPORTED_TYPE,
47            Self::NotNow => sys::SCS_RESULT_NOT_NOW,
48            Self::Generic => sys::SCS_RESULT_GENERIC_ERROR,
49            Self::Unknown(value) => value,
50        }
51    }
52}
53
54impl fmt::Display for SdkError {
55    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
56        match self {
57            Self::Unsupported => formatter.write_str("unsupported SDK operation or version"),
58            Self::InvalidParameter => formatter.write_str("invalid SDK parameter"),
59            Self::AlreadyRegistered => formatter.write_str("SDK callback is already registered"),
60            Self::NotFound => formatter.write_str("SDK event or channel was not found"),
61            Self::UnsupportedType => formatter.write_str("SDK value type is not supported"),
62            Self::NotNow => {
63                formatter.write_str("SDK operation is not allowed in the current state")
64            }
65            Self::Generic => formatter.write_str("generic SDK error"),
66            Self::Unknown(value) => write!(formatter, "unknown SDK result code {value}"),
67        }
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn preserves_all_sdk_result_codes() {
77        let cases = [
78            (sys::SCS_RESULT_UNSUPPORTED, SdkError::Unsupported),
79            (
80                sys::SCS_RESULT_INVALID_PARAMETER,
81                SdkError::InvalidParameter,
82            ),
83            (
84                sys::SCS_RESULT_ALREADY_REGISTERED,
85                SdkError::AlreadyRegistered,
86            ),
87            (sys::SCS_RESULT_NOT_FOUND, SdkError::NotFound),
88            (sys::SCS_RESULT_UNSUPPORTED_TYPE, SdkError::UnsupportedType),
89            (sys::SCS_RESULT_NOT_NOW, SdkError::NotNow),
90            (sys::SCS_RESULT_GENERIC_ERROR, SdkError::Generic),
91        ];
92
93        for (code, expected) in cases {
94            assert_eq!(SdkError::from_code(code), Err(expected));
95            assert_eq!(expected.code(), code);
96        }
97    }
98}