1 use crate::{error, UsbContext};
2 use libusb1_sys::{constants::*, libusb_set_option};
3 
4 /// A `libusb` runtime option that can be enabled for a context.
5 pub struct UsbOption {
6     inner: OptionInner,
7 }
8 
9 impl UsbOption {
10     /// Use the [UsbDk] backend if available.
11     ///
12     /// **Note**: This method is available on **Windows** only!
13     ///
14     /// [UsbDk]: https://github.com/daynix/UsbDk
15     #[cfg(windows)]
use_usbdk() -> Self16     pub fn use_usbdk() -> Self {
17         Self {
18             inner: OptionInner::UseUsbdk,
19         }
20     }
21 
apply<T: UsbContext>(&self, ctx: &mut T) -> crate::Result<()>22     pub(crate) fn apply<T: UsbContext>(&self, ctx: &mut T) -> crate::Result<()> {
23         match self.inner {
24             OptionInner::UseUsbdk => {
25                 let err = unsafe { libusb_set_option(ctx.as_raw(), LIBUSB_OPTION_USE_USBDK) };
26                 if err == LIBUSB_SUCCESS {
27                     Ok(())
28                 } else {
29                     Err(error::from_libusb(err))
30                 }
31             }
32         }
33     }
34 }
35 
36 enum OptionInner {
37     #[cfg_attr(not(windows), allow(dead_code))] // only constructed on Windows
38     UseUsbdk,
39 }
40 
41 /// Disable device scanning in `libusb` init.
42 ///
43 /// Hotplug functionality will also be deactivated.
44 ///
45 /// This is a Linux only option and it must be set before any [`Context`]
46 /// creation.
47 ///
48 /// The option is useful in combination with [`Context::open_device_with_fd()`],
49 /// which can access a device directly without prior device scanning.
50 #[cfg(unix)]
disable_device_discovery() -> crate::Result<()>51 pub fn disable_device_discovery() -> crate::Result<()> {
52     try_unsafe!(libusb1_sys::libusb_set_option(
53         std::ptr::null_mut(),
54         LIBUSB_OPTION_NO_DEVICE_DISCOVERY
55     ));
56     Ok(())
57 }
58