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