nng_c/
error.rs

1//!NNG error definition
2
3use core::ptr;
4use core::ffi::c_int;
5use core::ffi::CStr;
6
7pub use error_code::ErrorCode;
8
9use crate::sys;
10
11///Extension to error code with shortcut for some meaningful checks
12pub trait NngError {
13    ///Returns whether error code indicates cancellation of future.
14    fn is_cancelled(&self) -> bool;
15    ///Returns whether error code indicates operation timed out.
16    fn is_timed_out(&self) -> bool;
17    ///Returns whether error code indicates aborted connection.
18    fn is_conn_aborted(&self) -> bool;
19    ///Returns whether error code indicates connection has been reset.
20    fn is_conn_reset(&self) -> bool;
21    ///Returns whether error code indicates connection has been refused.
22    fn is_conn_refused(&self) -> bool;
23    ///Returns whether error code indicates problem with peer's authentication
24    fn is_peer_auth(&self) -> bool;
25    ///Returns whether error code indicates problem using crypto
26    ///
27    ///This is mostly indicates invalid local configuration (i.e. no TLS certificate etc)
28    fn is_crypto(&self) -> bool;
29}
30
31impl NngError for ErrorCode {
32    #[inline(always)]
33    fn is_cancelled(&self) -> bool {
34        self.raw_code() == sys::nng_errno_enum::NNG_ECANCELED
35    }
36
37    #[inline(always)]
38    fn is_timed_out(&self) -> bool {
39        self.raw_code() == sys::nng_errno_enum::NNG_ETIMEDOUT
40    }
41
42    #[inline(always)]
43    fn is_conn_aborted(&self) -> bool {
44        self.raw_code() == sys::nng_errno_enum::NNG_ECONNABORTED
45    }
46
47    #[inline(always)]
48    fn is_conn_reset(&self) -> bool {
49        self.raw_code() == sys::nng_errno_enum::NNG_ECONNRESET
50    }
51
52    #[inline(always)]
53    fn is_conn_refused(&self) -> bool {
54        self.raw_code() == sys::nng_errno_enum::NNG_ECONNREFUSED
55    }
56
57    #[inline(always)]
58    fn is_peer_auth(&self) -> bool {
59        self.raw_code() == sys::nng_errno_enum::NNG_EPEERAUTH
60    }
61
62    #[inline(always)]
63    fn is_crypto(&self) -> bool {
64        self.raw_code() == sys::nng_errno_enum::NNG_ECRYPTO
65    }
66}
67
68static CATEGORY: error_code::Category = error_code::Category {
69    name: "NngError",
70    equivalent,
71    is_would_block,
72    message,
73};
74
75fn equivalent(code: c_int, other: &ErrorCode) -> bool {
76    ptr::eq(&CATEGORY, other.category()) && code == other.raw_code()
77}
78
79fn is_would_block(code: c_int) -> bool {
80    code == nng_c_sys::nng_errno_enum::NNG_EAGAIN
81}
82
83fn message(code: c_int, _: &mut error_code::MessageBuf) -> &str {
84    //nng returns static buffer or constant therefore there is no need to copy message
85    let msg = unsafe {
86        CStr::from_ptr(
87            nng_c_sys::nng_strerror(code)
88        )
89    };
90
91    match msg.to_str() {
92        Ok(msg) => msg,
93        Err(_) => "Non-utf8 error message",
94    }
95}
96
97#[cold]
98#[inline(never)]
99///Creates new nng error
100pub(crate) fn error(code: c_int) -> ErrorCode {
101    ErrorCode::new(code, &CATEGORY)
102}