eusb 1.0.5

Rust library for accessing USB devices.
use std::ptr::{null_mut, slice_from_raw_parts};
use log::debug;
use crate::error::*;
use libusb_src::*;
use crate::platform::libusb::device::Device;
use crate::platform::libusb::errors::*;
use crate::platform::libusb::device_handle::DeviceHandle;
use crate::platform::*;


pub(crate) struct Context(*mut libusb_context);

unsafe impl Send for Context {}

unsafe impl Sync for Context {}

impl Context {
    pub(crate) fn new() -> Self {
        unsafe {
            let mut ptr = null_mut();

            #[cfg(target_os = "android")]
            check_err( libusb_set_option(ptr, LIBUSB_OPTION_NO_DEVICE_DISCOVERY)).unwrap();

            check_err(libusb_init(&mut ptr)).unwrap();
            debug!("libusb_init");
            Self(ptr)
        }
    }

    pub(crate) fn device_list(&self) -> Result<Vec<Device>> {
        unsafe {
            let mut devs_raw: *const *mut libusb_device = null_mut();
            let count = check_err(libusb_get_device_list(self.0, &mut devs_raw) as _)? as usize;
            let list = &*slice_from_raw_parts(devs_raw, count);
            let out: Vec<Device> = list.iter().copied().map(|o| o.into()).collect();
            libusb_free_device_list(devs_raw, 0);
            Ok(out)
        }
    }
    pub(crate) fn handle_events(&self, )->Result{
        unsafe {
            check_err(libusb_handle_events(self.0))?;
        }
        Ok(())
    }
    pub(crate) fn open_device_with_vid_pid(&self, vid: u16, pid: u16 )->Result<DeviceHandle>{
        unsafe {
            let h = libusb_open_device_with_vid_pid(self.0, vid, pid);
            if h.is_null() {
                return Err(Error::NotFound);
            }
            Ok(DeviceHandle::from(h))
        }
    }

    #[cfg(unix)]
    pub(crate) fn open_device_with_fd(&self, fd: RawFd)->Result<DeviceHandle>{
        unsafe {
            let mut handle= null_mut();
            check_err( libusb_wrap_sys_device(self.0, fd as _, &mut handle))?;
            Ok(DeviceHandle::from(handle))
        }
    }

    pub(crate) fn exit(&self){
        unsafe {
            if !self.0.is_null() {
                debug!("libusb_exit");
                libusb_exit(self.0);
            }
        }
    }
}