mirror of
https://github.com/G2-Games/cross-usb.git
synced 2025-04-19 13:22:53 -05:00
Replaced get_device
with get_device_filter
, doc improvements, other improvements
This commit is contained in:
parent
0af8b86c25
commit
6ac7479879
5 changed files with 44 additions and 88 deletions
|
@ -29,7 +29,6 @@ version = "0.3"
|
||||||
features = [
|
features = [
|
||||||
"Window",
|
"Window",
|
||||||
"Navigator",
|
"Navigator",
|
||||||
"console",
|
|
||||||
"Usb",
|
"Usb",
|
||||||
"UsbDevice",
|
"UsbDevice",
|
||||||
"UsbInterface",
|
"UsbInterface",
|
||||||
|
@ -39,7 +38,6 @@ features = [
|
||||||
"UsbDeviceRequestOptions",
|
"UsbDeviceRequestOptions",
|
||||||
"UsbInTransferResult",
|
"UsbInTransferResult",
|
||||||
"UsbOutTransferResult",
|
"UsbOutTransferResult",
|
||||||
"Storage"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Non-wasm deps
|
# Non-wasm deps
|
||||||
|
|
|
@ -36,34 +36,7 @@ impl DeviceFilter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, UsbError> {
|
pub async fn get_device(device_filter: Vec<DeviceFilter>) -> Result<UsbDevice, UsbError> {
|
||||||
let devices = nusb::list_devices().unwrap();
|
|
||||||
|
|
||||||
let mut device_info = None;
|
|
||||||
for device in devices {
|
|
||||||
if device.vendor_id() == vendor_id && device.product_id() == product_id {
|
|
||||||
device_info = Some(device);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let device_info = match device_info {
|
|
||||||
Some(dev) => dev,
|
|
||||||
None => return Err(UsbError::DeviceNotFound),
|
|
||||||
};
|
|
||||||
|
|
||||||
let device = match device_info.open() {
|
|
||||||
Ok(dev) => dev,
|
|
||||||
Err(_) => return Err(UsbError::CommunicationError),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(UsbDevice {
|
|
||||||
device_info,
|
|
||||||
device,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_device_filter(device_filter: Vec<DeviceFilter>) -> Result<UsbDevice, UsbError> {
|
|
||||||
let devices = nusb::list_devices().unwrap();
|
let devices = nusb::list_devices().unwrap();
|
||||||
|
|
||||||
let mut device_info = None;
|
let mut device_info = None;
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub struct UsbDevice {
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub struct UsbInterface {
|
pub struct UsbInterface {
|
||||||
device: WasmUsbDevice,
|
device: WasmUsbDevice,
|
||||||
|
_number: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
@ -50,56 +51,7 @@ impl DeviceFilter {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, js_sys::Error> {
|
pub async fn get_device(
|
||||||
let window = web_sys::window().unwrap();
|
|
||||||
|
|
||||||
let navigator = window.navigator();
|
|
||||||
let usb = navigator.usb();
|
|
||||||
|
|
||||||
let device_list: Array = JsFuture::from(Promise::resolve(&usb.get_devices()))
|
|
||||||
.await?
|
|
||||||
.into();
|
|
||||||
// Check if the device is already paired, if so, we don't need to request it again
|
|
||||||
for js_device in device_list {
|
|
||||||
let device: WasmUsbDevice = js_device.into();
|
|
||||||
|
|
||||||
if device.vendor_id() == vendor_id && device.product_id() == product_id {
|
|
||||||
let _open_promise = JsFuture::from(Promise::resolve(&device.open())).await?;
|
|
||||||
|
|
||||||
return Ok(UsbDevice { device });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let arr = Array::new();
|
|
||||||
let filter1 = js_sys::Object::new();
|
|
||||||
js_sys::Reflect::set(
|
|
||||||
&filter1,
|
|
||||||
&JsValue::from_str("vendorId"),
|
|
||||||
&JsValue::from(vendor_id),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
js_sys::Reflect::set(
|
|
||||||
&filter1,
|
|
||||||
&JsValue::from_str("productId"),
|
|
||||||
&JsValue::from(product_id),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
arr.push(&filter1);
|
|
||||||
let filters = JsValue::from(&arr);
|
|
||||||
|
|
||||||
let filters2 = UsbDeviceRequestOptions::new(&filters);
|
|
||||||
|
|
||||||
let device: WasmUsbDevice = JsFuture::from(Promise::resolve(&usb.request_device(&filters2)))
|
|
||||||
.await?
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let _open_promise = JsFuture::from(Promise::resolve(&device.open())).await?;
|
|
||||||
|
|
||||||
Ok(UsbDevice { device })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
|
||||||
pub async fn get_device_filter(
|
|
||||||
device_filter: Vec<DeviceFilter>,
|
device_filter: Vec<DeviceFilter>,
|
||||||
) -> Result<UsbDevice, js_sys::Error> {
|
) -> Result<UsbDevice, js_sys::Error> {
|
||||||
let window = web_sys::window().unwrap();
|
let window = web_sys::window().unwrap();
|
||||||
|
@ -107,9 +59,11 @@ pub async fn get_device_filter(
|
||||||
let navigator = window.navigator();
|
let navigator = window.navigator();
|
||||||
let usb = navigator.usb();
|
let usb = navigator.usb();
|
||||||
|
|
||||||
let device_list: Array = JsFuture::from(Promise::resolve(&usb.get_devices()))
|
let device_list: Array = match JsFuture::from(Promise::resolve(&usb.get_devices())).await {
|
||||||
.await?
|
Ok(list) => list.into(),
|
||||||
.into();
|
Err(_) => Array::new(),
|
||||||
|
};
|
||||||
|
|
||||||
// Check if the device is already paired, if so, we don't need to request it again
|
// Check if the device is already paired, if so, we don't need to request it again
|
||||||
for js_device in device_list {
|
for js_device in device_list {
|
||||||
let device: WasmUsbDevice = js_device.into();
|
let device: WasmUsbDevice = js_device.into();
|
||||||
|
@ -142,6 +96,7 @@ pub async fn get_device_filter(
|
||||||
result
|
result
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
let _open_promise = JsFuture::from(Promise::resolve(&device.open())).await?;
|
||||||
return Ok(UsbDevice { device });
|
return Ok(UsbDevice { device });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,13 +177,12 @@ impl Device for UsbDevice {
|
||||||
|
|
||||||
Ok(UsbInterface {
|
Ok(UsbInterface {
|
||||||
device: self.device.clone(),
|
device: self.device.clone(),
|
||||||
|
_number: number,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn reset(&self) -> Result<(), UsbError> {
|
async fn reset(&self) -> Result<(), UsbError> {
|
||||||
let promise = Promise::resolve(&self.device.reset());
|
let result = JsFuture::from(Promise::resolve(&self.device.reset())).await;
|
||||||
|
|
||||||
let result = JsFuture::from(promise).await;
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
|
@ -236,6 +190,17 @@ impl Device for UsbDevice {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
async fn forget(&self) -> Result<(), UsbError> {
|
||||||
|
let result = JsFuture::from(Promise::resolve(&self.device.forget())).await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(_) => Err(UsbError::CommunicationError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
async fn vendor_id(&self) -> u16 {
|
async fn vendor_id(&self) -> u16 {
|
||||||
self.device.vendor_id()
|
self.device.vendor_id()
|
||||||
}
|
}
|
||||||
|
|
13
src/lib.rs
13
src/lib.rs
|
@ -3,13 +3,24 @@
|
||||||
//! The idea is the user only has to write one way to access USB devices, which can be compiled
|
//! The idea is the user only has to write one way to access USB devices, which can be compiled
|
||||||
//! to both WASM and native targets without any conditional compilation or configuration.
|
//! to both WASM and native targets without any conditional compilation or configuration.
|
||||||
//!
|
//!
|
||||||
|
//! For native device support, this library uses [nusb](https://docs.rs/nusb/latest/nusb/), a cross platform USB library written in Rust
|
||||||
|
//! and comparable to the very popular `libusb` C library. Web Assembly support is provided by [web-sys](https://docs.rs/web-sys/latest/web_sys/)
|
||||||
|
//! with the [Web USB API](https://developer.mozilla.org/en-US/docs/Web/API/WebUSB_API)
|
||||||
|
//!
|
||||||
|
//! When a [UsbInterface] is dropped, it is automatically released.
|
||||||
|
//!
|
||||||
//! ## Example:
|
//! ## Example:
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! # tokio_test::block_on(async {
|
//! # tokio_test::block_on(async {
|
||||||
//! use cross_usb::usb::{Device, Interface, Recipient, ControlType, ControlIn};
|
//! use cross_usb::usb::{Device, Interface, Recipient, ControlType, ControlIn};
|
||||||
|
//! use cross_usb::device_filter;
|
||||||
//!
|
//!
|
||||||
//! // Obtain a device using its VendorID and ProductID
|
//! // Obtain a device using its VendorID and ProductID
|
||||||
//! let device = cross_usb::get_device(0x054c, 0x0186).await.expect("Failed to get device");
|
//! let filter = vec![
|
||||||
|
//! device_filter!{vendor_id: 0x054c, product_id: 0x00c9}
|
||||||
|
//! ];
|
||||||
|
//!
|
||||||
|
//! let device = cross_usb::get_device_filter(filter).await.expect("Failed to get device");
|
||||||
//!
|
//!
|
||||||
//! // Obtain an interface of the device
|
//! // Obtain an interface of the device
|
||||||
//! let interface = device.open_interface(0).await.expect("Failed to open interface");
|
//! let interface = device.open_interface(0).await.expect("Failed to open interface");
|
||||||
|
|
11
src/usb.rs
11
src/usb.rs
|
@ -16,9 +16,18 @@ pub trait Device {
|
||||||
/// Open a specific interface of the device
|
/// Open a specific interface of the device
|
||||||
async fn open_interface(&self, number: u8) -> Result<UsbInterface, UsbError>;
|
async fn open_interface(&self, number: u8) -> Result<UsbInterface, UsbError>;
|
||||||
|
|
||||||
/// Reset the device, which causes it to no longer be usable
|
/// Reset the device, which causes it to no longer be usable. You must
|
||||||
|
/// request a new device with [crate::get_device] or [crate::get_device_filter]
|
||||||
async fn reset(&self) -> Result<(), UsbError>;
|
async fn reset(&self) -> Result<(), UsbError>;
|
||||||
|
|
||||||
|
/*
|
||||||
|
/// Remove the device from the paired devices list, causing it to no longer be usable.
|
||||||
|
/// You must request to reconnect using [crate::get_device] or [crate::get_device_filter]
|
||||||
|
///
|
||||||
|
/// **Note: Only does anything on WASM, on Native it simply resets the device**
|
||||||
|
async fn forget(&self) -> Result<(), UsbError>;
|
||||||
|
*/
|
||||||
|
|
||||||
/// 16 bit device Product ID
|
/// 16 bit device Product ID
|
||||||
async fn product_id(&self) -> u16;
|
async fn product_id(&self) -> u16;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue