diff --git a/Cargo.toml b/Cargo.toml index cd62e9fe..3af50f09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ description = "List system USB buses and devices; a modern and compatible `lsusb repository = "https://github.com/tuna-f1sh/cyme" readme = "README.md" license = "GPL-3.0-or-later" -version = "1.2.2" +version = "1.2.3" edition = "2021" keywords = ["usb", "lsusb", "system_profiler", "macos", "libusb"] categories = ["command-line-utilities"] diff --git a/src/config.rs b/src/config.rs index bb3b48e7..b8bfe81a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,9 +5,9 @@ use std::io; use std::io::{BufReader, Read}; use std::path::{Path, PathBuf}; +use crate::colour; use crate::display; use crate::display::Block; -use crate::colour; use crate::icon; const CONF_DIR: &'static str = "cyme"; @@ -73,17 +73,21 @@ impl Config { let path = p.join(CONF_NAME); log::info!("Looking for cyme system config {:?}", &path); return match Self::from_file(&path) { - Ok(c) => { + Ok(c) => { log::info!("Loaded cyme system config {:?}", c); c - }, + } Err(e) => { if e.kind() != io::ErrorKind::NotFound { - log::warn!("Failed to read cyme system config {:?}: Error({})", &path, e); + log::warn!( + "Failed to read cyme system config {:?}: Error({})", + &path, + e + ); } Self::new() } - } + }; } Self::new() } diff --git a/src/display.rs b/src/display.rs index 58ad3574..24dfffe9 100644 --- a/src/display.rs +++ b/src/display.rs @@ -4,10 +4,10 @@ use clap::ValueEnum; use colored::*; use itertools::Itertools; +use rand::{distributions::Alphanumeric, seq::IteratorRandom, Rng}; use serde::{Deserialize, Serialize}; use std::cmp; use std::collections::HashMap; -use rand::{distributions::Alphanumeric, seq::IteratorRandom, Rng}; use crate::colour; use crate::icon; @@ -959,8 +959,7 @@ impl Block for InterfaceBlocks { InterfaceBlocks::Driver => ct.driver.map_or(s.normal(), |c| s.color(c)), InterfaceBlocks::AltSetting | InterfaceBlocks::NumEndpoints => { ct.number.map_or(s.normal(), |c| s.color(c)) - } - // _ => s.normal(), + } // _ => s.normal(), } } @@ -1199,8 +1198,7 @@ impl Block for EndpointBlocks { } EndpointBlocks::UsageType => { format!("{:^pad$}", "UsageT", pad = pad.get(self).unwrap_or(&0)) - } - // _ => "", + } // _ => "", } } } @@ -2034,19 +2032,28 @@ pub fn mask_serial(device: &mut system_profiler::USBDevice, hide: &MaskSerial, r if let Some(serial) = device.serial_num.as_mut() { *serial = match hide { MaskSerial::Hide => serial.chars().map(|_| '*').collect::(), - MaskSerial::Scramble => - serial.chars().map(|_| serial.chars().choose(&mut rand::thread_rng()).unwrap_or('*')).collect::(), - MaskSerial::Replace => - rand::thread_rng() - .sample_iter(Alphanumeric) - .take(serial.chars().count()) - .map(char::from) - .collect::().to_uppercase(), + MaskSerial::Scramble => serial + .chars() + .map(|_| { + serial + .chars() + .choose(&mut rand::thread_rng()) + .unwrap_or('*') + }) + .collect::(), + MaskSerial::Replace => rand::thread_rng() + .sample_iter(Alphanumeric) + .take(serial.chars().count()) + .map(char::from) + .collect::() + .to_uppercase(), }; } if recursive { - device.devices.as_mut().map_or((), |dd| dd.iter_mut().for_each(|d| mask_serial(d, hide, recursive))); + device.devices.as_mut().map_or((), |dd| { + dd.iter_mut().for_each(|d| mask_serial(d, hide, recursive)) + }); } } diff --git a/src/icon.rs b/src/icon.rs index 9058b175..181d8d2b 100644 --- a/src/icon.rs +++ b/src/icon.rs @@ -454,7 +454,10 @@ pub fn example() -> HashMap { /// Returns example theme with [`Icon`] types and default tree pub fn example_theme() -> IconTheme { - let tree_strings: HashMap = DEFAULT_TREE.iter().map(|(k, v)| (k.to_owned(), v.to_string())).collect(); + let tree_strings: HashMap = DEFAULT_TREE + .iter() + .map(|(k, v)| (k.to_owned(), v.to_string())) + .collect(); IconTheme { user: Some(example()), diff --git a/src/lsusb.rs b/src/lsusb.rs index f16b7346..d58624af 100644 --- a/src/lsusb.rs +++ b/src/lsusb.rs @@ -17,15 +17,15 @@ pub mod profiler { //! ``` //! //! See [`system_profiler`] docs for what can be done with returned data, such as [`system_profiler::USBFilter`] - use std::collections::HashMap; - use std::time::Duration; use itertools::Itertools; use rusb as libusb; + use std::collections::HashMap; + use std::time::Duration; use usb_ids::{self, FromId}; - use crate::{system_profiler, types::NumericalUnit, usb}; #[cfg(all(target_os = "linux", feature = "udev"))] use crate::udev; + use crate::{system_profiler, types::NumericalUnit, usb}; struct UsbDevice { handle: libusb::DeviceHandle, @@ -574,9 +574,7 @@ pub mod profiler { /// Fills a passed mutable `spusb` reference to fill using `get_spusb`. Will replace existing [`system_profiler::USBDevice`]s found in the libusb build but leave others and the buses. /// /// The main use case for this is to merge with macOS `system_profiler` data, so that [`usb::USBDeviceExtra`] can be obtained but internal buses kept. One could also use it to update a static .json dump. - pub fn fill_spusb( - spusb: &mut system_profiler::SPUSBDataType, - ) -> Result<(), libusb::Error> { + pub fn fill_spusb(spusb: &mut system_profiler::SPUSBDataType) -> Result<(), libusb::Error> { let libusb_spusb = get_spusb_with_extra()?; // merge if passed has any buses @@ -719,8 +717,12 @@ pub mod display { .expect("Cannot print verbose without extra data"); println!("Device Descriptor:"); - println!(" bcdUSB {}", - device.bcd_usb.as_ref().map_or(String::new(), |v| v.to_string()) + println!( + " bcdUSB {}", + device + .bcd_usb + .as_ref() + .map_or(String::new(), |v| v.to_string()) ); println!( " bDeviceClass {:3} {}", @@ -745,7 +747,10 @@ pub mod display { ); println!( " bcdDevice {}", - device.bcd_device.as_ref().map_or(String::new(), |v| v.to_string()) + device + .bcd_device + .as_ref() + .map_or(String::new(), |v| v.to_string()) ); println!( " iManufacturer {:3} {}", diff --git a/src/main.rs b/src/main.rs index 27017552..92e8ac7c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use cyme::usb::ClassCode; #[derive(Parser, Debug, Default, Serialize, Deserialize)] #[skip_serializing_none] -#[command(author, version, about, long_about = None)] +#[command(author, version, about, long_about = None, max_term_width=80)] struct Args { /// Attempt to maintain compatibility with lsusb output #[arg(short, long, default_value_t = false)] @@ -284,15 +284,19 @@ fn get_libusb_spusb(_args: &Args) -> system_profiler::SPUSBDataType { #[cfg(feature = "libusb")] fn get_libusb_spusb(args: &Args) -> system_profiler::SPUSBDataType { if args.verbose > 0 - || args.tree - || args.device.is_some() - || args.lsusb - || args.json - || args.more { + || args.tree + || args.device.is_some() + || args.lsusb + || args.json + || args.more + { lsusb::profiler::get_spusb_with_extra().unwrap_or_else(|e| { eprintexit!(std::io::Error::new( std::io::ErrorKind::Other, - format!("Failed to gather system USB data with extra from libusb: Error({})", e) + format!( + "Failed to gather system USB data with extra from libusb: Error({})", + e + ) )); }) } else { @@ -341,10 +345,10 @@ fn print_lsusb( #[cfg(feature = "cli_generate")] #[cold] fn print_man() -> Result<(), Error> { - use std::fs; use clap::CommandFactory; use clap_complete::generate_to; use clap_complete::shells::*; + use std::fs; use std::path::PathBuf; let outdir = std::env::var_os("BUILD_SCRIPT_DIR") diff --git a/src/system_profiler.rs b/src/system_profiler.rs index a946a428..19fd23c4 100644 --- a/src/system_profiler.rs +++ b/src/system_profiler.rs @@ -17,16 +17,16 @@ //! //! let spusb = system_profiler::get_spusb_with_extra().unwrap(); //! ``` +use colored::*; +use serde::de::{self, MapAccess, SeqAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::{skip_serializing_none, DeserializeFromStr, SerializeDisplay}; use std::fmt; -use std::io; use std::fs; +use std::io; +use std::io::Read; use std::process::Command; use std::str::FromStr; -use std::io::Read; -use serde::de::{self, MapAccess, SeqAccess, Visitor}; -use serde::{Deserialize, Deserializer, Serialize}; -use serde_with::{skip_serializing_none, DeserializeFromStr, SerializeDisplay}; -use colored::*; use crate::types::NumericalUnit; use crate::usb::*; @@ -666,10 +666,18 @@ pub struct USBDevice { pub serial_num: Option, /// The device manufacturer as provided in descriptor or using usb_ids if None pub manufacturer: Option, - #[serde(default, serialize_with = "version_serializer", deserialize_with = "deserialize_option_version_from_string")] + #[serde( + default, + serialize_with = "version_serializer", + deserialize_with = "deserialize_option_version_from_string" + )] /// The device release number set by the developer as a [`Version`] pub bcd_device: Option, - #[serde(default, serialize_with = "version_serializer", deserialize_with = "deserialize_option_version_from_string")] + #[serde( + default, + serialize_with = "version_serializer", + deserialize_with = "deserialize_option_version_from_string" + )] /// The highest version of USB the device supports as a [`Version`] pub bcd_usb: Option, #[serde(default, deserialize_with = "deserialize_option_number_from_string")] @@ -710,9 +718,10 @@ impl USBDevice { /// Does the device have an interface with `class` pub fn has_interface_class(&self, c: &ClassCode) -> bool { if let Some(extra) = self.extra.as_ref() { - extra.configurations.iter().any(|conf| { - conf.interfaces.iter().any(|i| i.class == *c) - }) + extra + .configurations + .iter() + .any(|conf| conf.interfaces.iter().any(|i| i.class == *c)) } else { false } @@ -990,12 +999,12 @@ impl USBDevice { /// Generate a String from self like lsusb default list device /// ``` - /// let d = cyme::system_profiler::USBDevice{ - /// name: String::from("Test device"), - /// manufacturer: Some(String::from("Test Devices Inc.")), + /// let d = cyme::system_profiler::USBDevice{ + /// name: String::from("Test device"), + /// manufacturer: Some(String::from("Test Devices Inc.")), /// vendor_id: Some(0x1234), /// product_id: Some(0x4321), - /// location_id: cyme::system_profiler::DeviceLocation { bus: 1, number: 4, tree_positions: vec![1, 2, 3] }, + /// location_id: cyme::system_profiler::DeviceLocation { bus: 1, number: 4, tree_positions: vec![1, 2, 3] }, /// ..Default::default() /// }; /// assert_eq!(d.to_lsusb_string(), "Bus 001 Device 004: ID 1234:4321 Test Devices Inc. Test device"); @@ -1285,13 +1294,10 @@ impl USBFilter { .map_or(false, |s| s.contains(n.as_str())) })) && (self.class.as_ref().map_or(true, |fc| { - device - .class - .as_ref() - .map_or(false, |c| c == fc) || device.has_interface_class(fc) + device.class.as_ref().map_or(false, |c| c == fc) || device.has_interface_class(fc) })) && !(self.exclude_empty_hub && device.is_hub() && !device.has_devices()) - && (!device.is_root_hub() || self.no_exclude_root_hub) + && (!device.is_root_hub() || self.no_exclude_root_hub) } /// Recursively retain only `USBBus` in `buses` with `USBDevice` matching filter @@ -1385,13 +1391,13 @@ pub fn get_spusb_with_extra() -> Result { let mut spusb = get_spusb().map_err(|e| { io::Error::new( io::ErrorKind::Other, - format!("Failed to parse system_profiler output: Error({})", e) + format!("Failed to parse system_profiler output: Error({})", e), ) })?; crate::lsusb::profiler::fill_spusb(&mut spusb).map_err(|e| { io::Error::new( io::ErrorKind::Other, - format!("Failed to gather system USB data from libusb: Error({})", e) + format!("Failed to gather system USB data from libusb: Error({})", e), ) })?; @@ -1403,7 +1409,7 @@ pub fn get_spusb_with_extra() -> Result { pub fn get_spusb_with_extra() -> Result { Err(io::Error::new( io::ErrorKind::Other, - "libusb feature is required to do this, install with `cargo install --features libusb`" + "libusb feature is required to do this, install with `cargo install --features libusb`", )) } @@ -1455,7 +1461,9 @@ where } } -fn deserialize_option_version_from_string<'de, D>(deserializer: D) -> Result, D::Error> +fn deserialize_option_version_from_string<'de, D>( + deserializer: D, +) -> Result, D::Error> where D: Deserializer<'de>, { diff --git a/src/usb.rs b/src/usb.rs index c12ecf77..fab59221 100644 --- a/src/usb.rs +++ b/src/usb.rs @@ -3,14 +3,14 @@ //! Also refering to [beyondlogic](https://beyondlogic.org/usbnutshell/usb5.shtml) //! //! There are some repeated/copied Enum defines from rusb in order to control Serialize/Deserialize and add impl +use clap::ValueEnum; use itertools::Itertools; use serde::{Deserialize, Serialize}; use serde_with::skip_serializing_none; +use std::convert::TryFrom; use std::fmt; -use std::str::FromStr; use std::io; -use std::convert::TryFrom; -use clap::ValueEnum; +use std::str::FromStr; use crate::types::NumericalUnit; @@ -81,7 +81,13 @@ impl std::fmt::Display for Version { /// ``` /// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:x}.{:x}{:x}", self.major(), self.minor() & 0x0F, self.sub_minor() & 0x0F) + write!( + f, + "{:x}.{:x}{:x}", + self.major(), + self.minor() & 0x0F, + self.sub_minor() & 0x0F + ) } } @@ -111,9 +117,9 @@ impl TryFrom for Version { fn try_from(f: f32) -> Result { let s = format!("{:2.2}", f); let (parse_ints, _): (Vec>, Vec<_>) = s - .split(".") - .map(|vs| vs.parse::()) - .partition(Result::is_ok); + .split(".") + .map(|vs| vs.parse::()) + .partition(Result::is_ok); let numbers: Vec = parse_ints.into_iter().map(|v| v.unwrap()).collect(); match numbers.get(0..2) { @@ -314,7 +320,6 @@ impl ClassCode { ClassCode::CDCCommunications => "Communications".into(), _ => self.to_title_case(), } - } /// Converts Pascal case enum to space separated on capitals @@ -778,7 +783,6 @@ pub fn get_dev_path(bus: u8, device_no: Option) -> String { } } - #[cfg(test)] mod tests { use super::*; diff --git a/tests/common/mod.rs b/tests/common/mod.rs index c58fcc20..55cd1420 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -14,7 +14,8 @@ pub const SYSTEM_PROFILER_DUMP_PATH: &'static str = "./tests/data/system_profile /// Dump using macOS system_profiler so no [`USBDeviceExtra`] pub const CYME_SP_TREE_DUMP: &'static str = "./tests/data/cyme_sp_macos_tree.json"; /// Dump using macOS system_profiler and libusb merge so with [`USBDeviceExtra`] -pub const CYME_LIBUSB_MERGE_MACOS_TREE_DUMP: &'static str = "./tests/data/cyme_libusb_merge_macos_tree.json"; +pub const CYME_LIBUSB_MERGE_MACOS_TREE_DUMP: &'static str = + "./tests/data/cyme_libusb_merge_macos_tree.json"; /// Dump using macOS force libusb merge so with [`USBDeviceExtra`] but not Apple internal buses pub const CYME_LIBUSB_MACOS_TREE_DUMP: &'static str = "./tests/data/cyme_libusb_macos_tree.json"; /// Dump using Linux with libusb so with [`USBDeviceExtra`] @@ -257,11 +258,17 @@ impl TestEnv { } /// Parses output back to SPUSBDataType and checks device with `port_path` exists in it - pub fn assert_output_contains_port_path(&self, dump_file: Option<&str>, args: &[&str], port_path: &str) { + pub fn assert_output_contains_port_path( + &self, + dump_file: Option<&str>, + args: &[&str], + port_path: &str, + ) { // Normalize both expected and actual output. let output = self.assert_success_and_get_output(dump_file, args); let actual = String::from_utf8_lossy(&output.stdout).to_string(); - let spdata_out = serde_json::from_str::(&actual).unwrap(); + let spdata_out = + serde_json::from_str::(&actual).unwrap(); assert_eq!(spdata_out.get_node(port_path).is_some(), true); } diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 8f8a32dc..d47c271e 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -141,4 +141,3 @@ fn test_tree_filtering() { false, ); } -