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