Skip to main content

neoradio2/
error.rs

1use std::os::raw::c_int;
2
3/// Errors returned by the neoRAD-IO2 API.
4#[derive(Debug, Clone, PartialEq, Eq)]
5#[non_exhaustive]
6pub enum Error {
7    /// General failure (`NEORADIO2_FAILURE` / `NEORADIO2_ERR_FAILURE`).
8    Failure,
9    /// Non-blocking call would block (`NEORADIO2_ERR_WBLOCK`).
10    WouldBlock,
11    /// Non-blocking operation still in progress (`NEORADIO2_ERR_INPROGRESS`).
12    InProgress,
13    /// A Rust string contained an interior NUL byte.
14    NulByte,
15}
16
17impl std::fmt::Display for Error {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        let s = match self {
20            Error::Failure => "neoRAD-IO2 operation failed",
21            Error::WouldBlock => "operation would block (non-blocking mode)",
22            Error::InProgress => "operation in progress (non-blocking mode)",
23            Error::NulByte => "string contained an interior NUL byte",
24        };
25        f.write_str(s)
26    }
27}
28
29impl std::error::Error for Error {}
30
31/// Crate result type.
32pub type Result<T> = std::result::Result<T, Error>;
33
34/// Map a C return code to a `Result`.
35pub(crate) fn check(code: c_int) -> Result<()> {
36    match code {
37        0 => Ok(()),
38        2 => Err(Error::WouldBlock),
39        3 => Err(Error::InProgress),
40        _ => Err(Error::Failure),
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47    #[test]
48    fn maps_return_codes() {
49        assert!(check(0).is_ok());
50        assert_eq!(check(1).unwrap_err(), Error::Failure);
51        assert_eq!(check(2).unwrap_err(), Error::WouldBlock);
52        assert_eq!(check(3).unwrap_err(), Error::InProgress);
53        assert_eq!(check(4).unwrap_err(), Error::Failure);
54        assert_eq!(check(99).unwrap_err(), Error::Failure);
55    }
56}