1 use std::{fmt, result};
2 
3 #[cfg(feature = "serde")]
4 use serde::{Deserialize, Serialize};
5 
6 use libusb1_sys::constants::*;
7 
8 /// A result of a function that may return a `Error`.
9 pub type Result<T> = result::Result<T, Error>;
10 
11 /// Errors returned by the `libusb` library.
12 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
13 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14 pub enum Error {
15     /// Input/output error.
16     Io,
17 
18     /// Invalid parameter.
19     InvalidParam,
20 
21     /// Access denied (insufficient permissions).
22     Access,
23 
24     /// No such device (it may have been disconnected).
25     NoDevice,
26 
27     /// Entity not found.
28     NotFound,
29 
30     /// Resource busy.
31     Busy,
32 
33     /// Operation timed out.
34     Timeout,
35 
36     /// Overflow.
37     Overflow,
38 
39     /// Pipe error.
40     Pipe,
41 
42     /// System call interrupted (perhaps due to signal).
43     Interrupted,
44 
45     /// Insufficient memory.
46     NoMem,
47 
48     /// Operation not supported or unimplemented on this platform.
49     NotSupported,
50 
51     /// The device returned a malformed descriptor.
52     BadDescriptor,
53 
54     /// Other error.
55     Other,
56 }
57 
58 impl fmt::Display for Error {
fmt(&self, fmt: &mut fmt::Formatter) -> result::Result<(), fmt::Error>59     fn fmt(&self, fmt: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
60         fmt.write_str(match self {
61             Error::Io => "Input/Output Error",
62             Error::InvalidParam => "Invalid parameter",
63             Error::Access => "Access denied (insufficient permissions)",
64             Error::NoDevice => "No such device (it may have been disconnected)",
65             Error::NotFound => "Entity not found",
66             Error::Busy => "Resource busy",
67             Error::Timeout => "Operation timed out",
68             Error::Overflow => "Overflow",
69             Error::Pipe => "Pipe error",
70             Error::Interrupted => "System call interrupted (perhaps due to signal)",
71             Error::NoMem => "Insufficient memory",
72             Error::NotSupported => "Operation not supported or unimplemented on this platform",
73             Error::BadDescriptor => "Malformed descriptor",
74             Error::Other => "Other error",
75         })
76     }
77 }
78 
79 impl std::error::Error for Error {}
80 
81 #[doc(hidden)]
from_libusb(err: i32) -> Error82 pub(crate) fn from_libusb(err: i32) -> Error {
83     match err {
84         LIBUSB_ERROR_IO => Error::Io,
85         LIBUSB_ERROR_INVALID_PARAM => Error::InvalidParam,
86         LIBUSB_ERROR_ACCESS => Error::Access,
87         LIBUSB_ERROR_NO_DEVICE => Error::NoDevice,
88         LIBUSB_ERROR_NOT_FOUND => Error::NotFound,
89         LIBUSB_ERROR_BUSY => Error::Busy,
90         LIBUSB_ERROR_TIMEOUT => Error::Timeout,
91         LIBUSB_ERROR_OVERFLOW => Error::Overflow,
92         LIBUSB_ERROR_PIPE => Error::Pipe,
93         LIBUSB_ERROR_INTERRUPTED => Error::Interrupted,
94         LIBUSB_ERROR_NO_MEM => Error::NoMem,
95         LIBUSB_ERROR_NOT_SUPPORTED => Error::NotSupported,
96         LIBUSB_ERROR_OTHER | _ => Error::Other,
97     }
98 }
99 
100 #[doc(hidden)]
101 macro_rules! try_unsafe {
102     ($x:expr) => {
103         match unsafe { $x } {
104             0 => (),
105             err => return Err($crate::error::from_libusb(err)),
106         }
107     };
108 }
109