Added macro for DeviceFilter

This commit is contained in:
G2-Games 2024-02-01 16:05:06 -06:00
parent 2ea7fd68c8
commit 847367c9a9
3 changed files with 75 additions and 65 deletions

View file

@ -9,6 +9,33 @@ pub struct UsbInterface {
interface: nusb::Interface, interface: nusb::Interface,
} }
#[derive(PartialEq, Clone, Default)]
pub struct DeviceFilter {
pub vendor_id: Option<u16>,
pub product_id: Option<u16>,
pub class: Option<u8>,
pub subclass: Option<u8>,
pub protocol: Option<u8>,
}
impl DeviceFilter {
pub fn new(
vendor_id: Option<u16>,
product_id: Option<u16>,
class: Option<u8>,
subclass: Option<u8>,
protocol: Option<u8>,
) -> Self {
Self {
vendor_id,
product_id,
class,
subclass,
protocol,
}
}
}
pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, UsbError> { pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, UsbError> {
let devices = nusb::list_devices().unwrap(); let devices = nusb::list_devices().unwrap();
@ -36,35 +63,6 @@ pub async fn get_device(vendor_id: u16, product_id: u16) -> Result<UsbDevice, Us
}) })
} }
#[derive(PartialEq, Clone)]
pub struct DeviceFilter {
pub vendor_id: Option<u16>,
pub product_id: Option<u16>,
pub class: Option<u8>,
pub subclass: Option<u8>,
pub protocol: Option<u8>,
serial_number: Option<String>,
}
impl DeviceFilter {
pub fn serial_number(&self) -> &Option<String> {
&self.serial_number
}
}
impl Default for DeviceFilter {
fn default() -> Self {
Self {
vendor_id: None,
product_id: None,
class: None,
subclass: None,
protocol: None,
serial_number: None,
}
}
}
pub async fn get_device_filter( pub async fn get_device_filter(
device_filter: Vec<DeviceFilter>, device_filter: Vec<DeviceFilter>,
) -> Result<UsbDevice, UsbError> { ) -> Result<UsbDevice, UsbError> {
@ -97,10 +95,6 @@ pub async fn get_device_filter(
result = info.protocol.unwrap() == prelim_dev_inf.protocol(); result = info.protocol.unwrap() == prelim_dev_inf.protocol();
} }
if info.serial_number().is_some() && prelim_dev_inf.serial_number().is_some() {
result = info.serial_number().as_ref().unwrap() == &prelim_dev_inf.serial_number().unwrap().to_owned();
}
result result
} }
).is_some() { ).is_some() {

View file

@ -22,31 +22,29 @@ pub struct UsbInterface {
} }
#[wasm_bindgen] #[wasm_bindgen]
#[derive(PartialEq, Clone)] #[derive(PartialEq, Clone, Default)]
pub struct DeviceFilter { pub struct DeviceFilter {
pub vendor_id: Option<u16>, pub vendor_id: Option<u16>,
pub product_id: Option<u16>, pub product_id: Option<u16>,
pub class: Option<u8>, pub class: Option<u8>,
pub subclass: Option<u8>, pub subclass: Option<u8>,
pub protocol: Option<u8>, pub protocol: Option<u8>,
serial_number: Option<String>,
} }
impl DeviceFilter { impl DeviceFilter {
pub fn serial_number(&self) -> &Option<String> { pub fn new(
&self.serial_number vendor_id: Option<u16>,
} product_id: Option<u16>,
} class: Option<u8>,
subclass: Option<u8>,
impl Default for DeviceFilter { protocol: Option<u8>,
fn default() -> Self { ) -> Self {
Self { Self {
vendor_id: None, vendor_id,
product_id: None, product_id,
class: None, class,
subclass: None, subclass,
protocol: None, protocol,
serial_number: None,
} }
} }
} }
@ -140,10 +138,6 @@ pub async fn get_device_filter(
result = info.protocol.unwrap() == device.device_protocol(); result = info.protocol.unwrap() == device.device_protocol();
} }
if info.serial_number().is_some() && device.serial_number().is_some() {
result = info.serial_number().as_ref().unwrap() == &device.serial_number().unwrap().to_owned();
}
result result
} }
).is_some() { ).is_some() {
@ -194,14 +188,6 @@ pub async fn get_device_filter(
) )
.unwrap(); .unwrap();
} }
if let Some(serial) = filter.serial_number {
js_sys::Reflect::set(
&js_filter,
&JsValue::from_str("serialNumber"),
&JsValue::from(serial),
)
.unwrap();
}
arr.push(&js_filter); arr.push(&js_filter);
} }

View file

@ -48,8 +48,8 @@ pub use crate::context::UsbDevice;
/// An implementation of a USB interface /// An implementation of a USB interface
pub use crate::context::UsbInterface; pub use crate::context::UsbInterface;
/// A single Device ID and Product ID pair to find when looking /// Information about a USB device for finding it while trying
/// for new USB devices using [get_device_filter] /// to look for new USB devices using [get_device_filter]
#[doc(inline)] #[doc(inline)]
pub use crate::context::DeviceFilter; pub use crate::context::DeviceFilter;
@ -62,11 +62,12 @@ pub use crate::context::get_device;
/// ## Example /// ## Example
/// ```no_run /// ```no_run
/// # tokio_test::block_on(async { /// # tokio_test::block_on(async {
/// use cross_usb::{get_device_filter, FilterTuple}; /// use cross_usb::{get_device_filter, DeviceFilter, device_filter};
///
/// ///
/// let filter = vec![ /// let filter = vec![
/// FilterTuple(0x054c, 0x00c9), /// device_filter!{vendor_id: 0x054c, product_id: 0x00c9},
/// FilterTuple(0x054c, 0x0186), /// device_filter!{vendor_id: 0x054c},
/// ]; /// ];
/// ///
/// let device = get_device_filter(filter).await.expect("Could not find device in list"); /// let device = get_device_filter(filter).await.expect("Could not find device in list");
@ -74,3 +75,32 @@ pub use crate::context::get_device;
/// ``` /// ```
#[doc(inline)] #[doc(inline)]
pub use crate::context::get_device_filter; pub use crate::context::get_device_filter;
/// Macro to create a device filter easily from data.
///
/// The only valid keys are fields of the [DeviceFilter] struct.
/// You may use as many or as few of them as you need, the rest
/// of the values will be filled with [None].
///
/// ## Usage
/// ```
/// use cross_usb::device_filter;
///
/// // Example with all fields filled
/// device_filter!{
/// vendor_id: 0x054c,
/// product_id: 0x0186,
/// class: 0xFF,
/// subclass: 0x02,
/// protocol: 0x15,
/// };
/// ```
#[macro_export]
macro_rules! device_filter {
($($field:ident: $val:expr),+ $(,)?) => {
cross_usb::DeviceFilter {
$($field: Some($val),)*
..cross_usb::DeviceFilter::default()
}
}
}