Struct HidApi

Source
pub struct HidApi { /* private fields */ }
Expand description

Object for handling hidapi context and implementing RAII for it. Only one instance can exist at a time.

Implementations§

Source§

impl HidApi

Source

pub fn new() -> HidResult<Self>

Initializes the hidapi.

Will also initialize the currently available device list.

Examples found in repository?
examples/readhid.rs (line 18)
17fn main() {
18    let api = HidApi::new().expect("Failed to create API instance");
19
20    let joystick = api.open(1103, 45320).expect("Failed to open device");
21
22    loop {
23        let mut buf = [0u8; 256];
24        let res = joystick.read(&mut buf[..]).unwrap();
25
26        let mut data_string = String::new();
27
28        for u in &buf[..res] {
29            data_string.push_str(&(u.to_string() + "\t"));
30        }
31
32        println!("{}", data_string);
33    }
34}
More examples
Hide additional examples
examples/static_lifetime_bound.rs (line 27)
26fn test_lt() -> Rc<HidDevice> {
27    let api = HidApi::new().expect("Hidapi init failed");
28
29    let mut devices = api.device_list();
30
31    let dev_info = devices
32        .nth(0)
33        .expect("There is not a single hid device available");
34
35    let dev = Rc::new(
36        api.open(dev_info.vendor_id(), dev_info.product_id())
37            .expect("Can not open device"),
38    );
39
40    let dev_1 = dev.clone();
41    requires_static_lt_bound(move || {
42        println!("{}", dev_1.check_error().unwrap()); //<! Can be captured by closure with static lt
43    });
44
45    dev //<! Can be returned from a function, which exceeds the lifetime of the API context
46}
examples/open_first_device.rs (line 19)
18    fn run() -> Result<(), HidError> {
19        let hidapi = HidApi::new()?;
20
21        let device_info = hidapi
22            .device_list()
23            .next()
24            .expect("No devices are available!")
25            .clone();
26
27        println!(
28            "Opening device:\n VID: {:04x}, PID: {:04x}\n",
29            device_info.vendor_id(),
30            device_info.product_id()
31        );
32
33        let device = device_info.open_device(&hidapi)?;
34
35        let mut buf = vec![0; 64];
36
37        println!("Reading data from device ...\n");
38
39        loop {
40            let len = device.read(&mut buf)?;
41            println!("{:?}", &buf[..len]);
42        }
43    }
examples/lshid.rs (line 19)
16fn main() {
17    println!("Printing all available hid devices:");
18
19    match HidApi::new() {
20        Ok(api) => {
21            for device in api.device_list() {
22                println!(
23                    "VID: {:04x}, PID: {:04x}, Serial: {}, Product name: {}",
24                    device.vendor_id(),
25                    device.product_id(),
26                    match device.serial_number() {
27                        Some(s) => s,
28                        _ => "<COULD NOT FETCH>",
29                    },
30                    match device.product_string() {
31                        Some(s) => s,
32                        _ => "<COULD NOT FETCH>",
33                    }
34                );
35            }
36        }
37        Err(e) => {
38            eprintln!("Error: {}", e);
39        }
40    }
41}
examples/co2mon.rs (line 91)
90fn main() {
91    let api = HidApi::new().expect("HID API object creation failed");
92
93    let dev = open_device(&api);
94
95    dev.send_feature_report(&[0; PACKET_SIZE])
96        .expect("Feature report failed");
97
98    println!(
99        "Manufacurer:\t{:?}",
100        dev.get_manufacturer_string()
101            .expect("Failed to read manufacurer string")
102    );
103    println!(
104        "Product:\t{:?}",
105        dev.get_product_string()
106            .expect("Failed to read product string")
107    );
108    println!(
109        "Serial number:\t{:?}",
110        dev.get_serial_number_string()
111            .expect("Failed to read serial number")
112    );
113
114    loop {
115        let mut buf = [0; PACKET_SIZE];
116        match dev.read_timeout(&mut buf[..], HID_TIMEOUT) {
117            Ok(PACKET_SIZE) => (),
118            Ok(res) => {
119                println!("Error: unexpected length of data: {}/{}", res, PACKET_SIZE);
120                continue;
121            }
122            Err(err) => {
123                println!("Error: {:}", err);
124                sleep(Duration::from_secs(RETRY_SEC));
125                continue;
126            }
127        }
128        match decode_buf(buf) {
129            CO2Result::Temperature(val) => println!("Temp:\t{:?}", val),
130            CO2Result::Concentration(val) => println!("Conc:\t{:?}", val),
131            CO2Result::Unknown(..) => (),
132            CO2Result::Error(val) => {
133                println!("Error:\t{}", val);
134                sleep(Duration::from_secs(RETRY_SEC));
135            }
136        }
137    }
138}
Source

pub fn refresh_devices(&mut self) -> HidResult<()>

Refresh devices list and information about them (to access them use device_list() method)

Source

pub fn devices(&self) -> &Vec<HidDeviceInfo>

👎Deprecated

Returns vec of objects containing information about connected devices

Deprecated. Use HidApi::device_list() instead.

Source

pub fn device_list(&self) -> impl Iterator<Item = &DeviceInfo>

Returns iterator containing information about attached HID devices.

Examples found in repository?
examples/static_lifetime_bound.rs (line 29)
26fn test_lt() -> Rc<HidDevice> {
27    let api = HidApi::new().expect("Hidapi init failed");
28
29    let mut devices = api.device_list();
30
31    let dev_info = devices
32        .nth(0)
33        .expect("There is not a single hid device available");
34
35    let dev = Rc::new(
36        api.open(dev_info.vendor_id(), dev_info.product_id())
37            .expect("Can not open device"),
38    );
39
40    let dev_1 = dev.clone();
41    requires_static_lt_bound(move || {
42        println!("{}", dev_1.check_error().unwrap()); //<! Can be captured by closure with static lt
43    });
44
45    dev //<! Can be returned from a function, which exceeds the lifetime of the API context
46}
More examples
Hide additional examples
examples/open_first_device.rs (line 22)
18    fn run() -> Result<(), HidError> {
19        let hidapi = HidApi::new()?;
20
21        let device_info = hidapi
22            .device_list()
23            .next()
24            .expect("No devices are available!")
25            .clone();
26
27        println!(
28            "Opening device:\n VID: {:04x}, PID: {:04x}\n",
29            device_info.vendor_id(),
30            device_info.product_id()
31        );
32
33        let device = device_info.open_device(&hidapi)?;
34
35        let mut buf = vec![0; 64];
36
37        println!("Reading data from device ...\n");
38
39        loop {
40            let len = device.read(&mut buf)?;
41            println!("{:?}", &buf[..len]);
42        }
43    }
examples/lshid.rs (line 21)
16fn main() {
17    println!("Printing all available hid devices:");
18
19    match HidApi::new() {
20        Ok(api) => {
21            for device in api.device_list() {
22                println!(
23                    "VID: {:04x}, PID: {:04x}, Serial: {}, Product name: {}",
24                    device.vendor_id(),
25                    device.product_id(),
26                    match device.serial_number() {
27                        Some(s) => s,
28                        _ => "<COULD NOT FETCH>",
29                    },
30                    match device.product_string() {
31                        Some(s) => s,
32                        _ => "<COULD NOT FETCH>",
33                    }
34                );
35            }
36        }
37        Err(e) => {
38            eprintln!("Error: {}", e);
39        }
40    }
41}
Source

pub fn open(&self, vid: u16, pid: u16) -> HidResult<HidDevice>

Open a HID device using a Vendor ID (VID) and Product ID (PID).

When multiple devices with the same vid and pid are available, then the first one found in the internal device list will be used. There are however no guarantees, which device this will be.

Examples found in repository?
examples/co2mon.rs (line 80)
78fn open_device(api: &HidApi) -> HidDevice {
79    loop {
80        match api.open(DEV_VID, DEV_PID) {
81            Ok(dev) => return dev,
82            Err(err) => {
83                println!("{}", err);
84                sleep(Duration::from_secs(RETRY_SEC));
85            }
86        }
87    }
88}
More examples
Hide additional examples
examples/readhid.rs (line 20)
17fn main() {
18    let api = HidApi::new().expect("Failed to create API instance");
19
20    let joystick = api.open(1103, 45320).expect("Failed to open device");
21
22    loop {
23        let mut buf = [0u8; 256];
24        let res = joystick.read(&mut buf[..]).unwrap();
25
26        let mut data_string = String::new();
27
28        for u in &buf[..res] {
29            data_string.push_str(&(u.to_string() + "\t"));
30        }
31
32        println!("{}", data_string);
33    }
34}
examples/static_lifetime_bound.rs (line 36)
26fn test_lt() -> Rc<HidDevice> {
27    let api = HidApi::new().expect("Hidapi init failed");
28
29    let mut devices = api.device_list();
30
31    let dev_info = devices
32        .nth(0)
33        .expect("There is not a single hid device available");
34
35    let dev = Rc::new(
36        api.open(dev_info.vendor_id(), dev_info.product_id())
37            .expect("Can not open device"),
38    );
39
40    let dev_1 = dev.clone();
41    requires_static_lt_bound(move || {
42        println!("{}", dev_1.check_error().unwrap()); //<! Can be captured by closure with static lt
43    });
44
45    dev //<! Can be returned from a function, which exceeds the lifetime of the API context
46}
Source

pub fn open_serial(&self, vid: u16, pid: u16, sn: &str) -> HidResult<HidDevice>

Open a HID device using a Vendor ID (VID), Product ID (PID) and a serial number.

Source

pub fn open_path(&self, device_path: &CStr) -> HidResult<HidDevice>

The path name be determined by inspecting the device list available with HidApi::devices()

Alternatively a platform-specific path name can be used (eg: /dev/hidraw0 on Linux).

Source

pub fn wrap_sys_device( &self, sys_dev: i32, interface_num: i32, ) -> HidResult<HidDevice>

Open a HID device using libusb_wrap_sys_device. Useful for Android.

§Arguments
  • sys_dev: Platform-specific file descriptor that can be recognised by libusb.
  • interface_num: USB interface number of the device to be used as HID interface. Pass -1 to select first HID interface of the device.
Source

pub fn check_error(&self) -> HidResult<HidError>

Get the last non-device specific error, which happened in the underlying hidapi C library. To get the last device specific error, use HidDevice::check_error.

The Ok() variant of the result will contain a HidError::HidApiError.

When Err() is returned, then acquiring the error string from the hidapi C library failed. The contained HidError is the cause, why no error could be fetched.

Auto Trait Implementations§

§

impl Freeze for HidApi

§

impl RefUnwindSafe for HidApi

§

impl Send for HidApi

§

impl Sync for HidApi

§

impl Unpin for HidApi

§

impl UnwindSafe for HidApi

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.