Skip to content

Commit

Permalink
Merge pull request #14 from haata/udev_istring_support
Browse files Browse the repository at this point in the history
Add udev iManufacturer/iProduct/iSerial support to linux
  • Loading branch information
tuna-f1sh authored Nov 13, 2023
2 parents 02642ce + e5a1f90 commit 3e1851e
Show file tree
Hide file tree
Showing 11 changed files with 249 additions and 128 deletions.
7 changes: 3 additions & 4 deletions examples/extra_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ use cyme::lsusb::profiler;

fn main() -> Result<(), String> {
// get all system devices - this time with extra data which contain the USBConfiguration, driver data (with udev)
let sp_usb = profiler::get_spusb_with_extra(false).map_err(|e| {
format!("Failed to gather system USB data from libusb, Error({})", e)
})?;
let sp_usb = profiler::get_spusb_with_extra(false)
.map_err(|e| format!("Failed to gather system USB data from libusb, Error({})", e))?;

let devices = sp_usb.flatten_devices();

Expand All @@ -14,7 +13,7 @@ fn main() -> Result<(), String> {
println!("Device {} has configurations:", device.name);
for c in extra.configurations.iter() {
println!("{:?}", c);
};
}
});
}

Expand Down
11 changes: 6 additions & 5 deletions examples/filter_devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
///
/// See [`USBFilter`] docs for more information
use cyme::lsusb::profiler;
use cyme::usb::ClassCode;
use cyme::system_profiler::USBFilter;
use cyme::usb::ClassCode;

fn main() -> Result<(), String> {
// get all system devices
let mut sp_usb = profiler::get_spusb(false).map_err(|e| {
format!("Failed to gather system USB data from libusb, Error({})", e)
})?;
let mut sp_usb = profiler::get_spusb(false)
.map_err(|e| format!("Failed to gather system USB data from libusb, Error({})", e))?;

// if one does want the tree, use the utility
let filter = USBFilter {
Expand All @@ -19,7 +18,9 @@ fn main() -> Result<(), String> {

// will retain only the buses that have devices that match the filter - parent devices such as hubs with a HID device will be retained
filter.retain_buses(&mut sp_usb.buses);
sp_usb.buses.retain(|b| b.devices.as_ref().map_or(false, |d| d.is_empty()));
sp_usb
.buses
.retain(|b| b.devices.as_ref().map_or(false, |d| d.is_empty()));

// if one does not care about the tree, flatten the devices and do manually
// let hid_devices = sp_usb.flatten_devices().iter().filter(|d| d.class == Some(ClassCode::HID));
Expand Down
7 changes: 3 additions & 4 deletions examples/print_devices.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use cyme::lsusb::profiler;
use cyme::display;
use cyme::lsusb::profiler;

fn main() -> Result<(), String> {
// get all system devices - use get_spusb_with_extra for verbose info
let sp_usb = profiler::get_spusb(false).map_err(|e| {
format!("Failed to gather system USB data from libusb, Error({})", e)
})?;
let sp_usb = profiler::get_spusb(false)
.map_err(|e| format!("Failed to gather system USB data from libusb, Error({})", e))?;

// flatten since we don't care tree/buses
let devices = sp_usb.flatten_devices();
Expand Down
5 changes: 2 additions & 3 deletions examples/walk_sp_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ fn recusive_map_devices(device: &USBDevice) {

fn main() -> Result<(), String> {
// get all system devices
let sp_usb = profiler::get_spusb(false).map_err(|e| {
format!("Failed to gather system USB data from libusb, Error({})", e)
})?;
let sp_usb = profiler::get_spusb(false)
.map_err(|e| format!("Failed to gather system USB data from libusb, Error({})", e))?;

// SPUSBDataType contains buses...
for bus in sp_usb.buses {
Expand Down
7 changes: 2 additions & 5 deletions src/colour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,7 @@ where
match ColorOrNull::deserialize(deserializer)? {
ColorOrNull::Str(s) => match s {
"" => Ok(None),
_ => Color::try_from(s)
.map(Some)
.map_err(serde::de::Error::custom),
_ => Ok(Some(Color::from(s))),
},
ColorOrNull::FromStr(i) => Ok(Some(i)),
ColorOrNull::Null => Ok(None),
Expand All @@ -222,8 +220,7 @@ where
where
E: serde::de::Error,
{
Color::try_from(value)
.map_err(|_| E::invalid_value(serde::de::Unexpected::Str(value), &self))
Ok(Color::from(value))
}

fn visit_seq<M>(self, mut seq: M) -> Result<Color, M::Error>
Expand Down
88 changes: 31 additions & 57 deletions src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,9 +612,7 @@ impl Block<DeviceBlocks, USBDevice> for DeviceBlocks {
}
}

fn generate_padding(
d: &[&system_profiler::USBDevice],
) -> HashMap<Self, usize> {
fn generate_padding(d: &[&system_profiler::USBDevice]) -> HashMap<Self, usize> {
DeviceBlocks::iter()
.map(|b| (b, cmp::max(b.heading().len(), b.len(d))))
.collect()
Expand Down Expand Up @@ -871,9 +869,7 @@ impl Block<BusBlocks, USBBus> for BusBlocks {
}
}

fn generate_padding(
d: &[&USBBus],
) -> HashMap<Self, usize> {
fn generate_padding(d: &[&USBBus]) -> HashMap<Self, usize> {
BusBlocks::iter()
.map(|b| (b, cmp::max(b.heading().len(), b.len(d))))
.collect()
Expand Down Expand Up @@ -1004,9 +1000,7 @@ impl Block<ConfigurationBlocks, USBConfiguration> for ConfigurationBlocks {
}
}

fn generate_padding(
d: &[&USBConfiguration],
) -> HashMap<Self, usize> {
fn generate_padding(d: &[&USBConfiguration]) -> HashMap<Self, usize> {
ConfigurationBlocks::iter()
.map(|b| (b, cmp::max(b.heading().len(), b.len(d))))
.collect()
Expand Down Expand Up @@ -1401,10 +1395,7 @@ pub enum Sort {

impl Sort {
/// The clone and sort the [`USBDevice`]s `d`
pub fn sort_devices(
&self,
d: &Vec<USBDevice>,
) -> Vec<USBDevice> {
pub fn sort_devices(&self, d: &Vec<USBDevice>) -> Vec<USBDevice> {
let mut sorted = d.to_owned();
match self {
Sort::BranchPosition => sorted.sort_by_key(|d| d.get_branch_position()),
Expand All @@ -1416,10 +1407,7 @@ impl Sort {
}

/// The clone and sort the references to [`USBDevice`]s `d`
pub fn sort_devices_ref<'a>(
&self,
d: &Vec<&'a USBDevice>,
) -> Vec<&'a USBDevice> {
pub fn sort_devices_ref<'a>(&self, d: &Vec<&'a USBDevice>) -> Vec<&'a USBDevice> {
let mut sorted = d.to_owned();
match self {
Sort::BranchPosition => sorted.sort_by_key(|d| d.get_branch_position()),
Expand Down Expand Up @@ -1812,10 +1800,7 @@ fn generate_extra_blocks(
}

/// Print `devices` `USBDevice` references without looking down each device's devices!
pub fn print_flattened_devices(
devices: &Vec<&USBDevice>,
settings: &PrintSettings,
) {
pub fn print_flattened_devices(devices: &Vec<&USBDevice>, settings: &PrintSettings) {
let mut db = settings
.device_blocks
.to_owned()
Expand Down Expand Up @@ -1908,15 +1893,13 @@ pub fn print_flattened_devices(
/// A way of printing a reference flattened `SPUSBDataType` rather than hard flatten
///
/// Prints each `&USBBus` and tuple pair `Vec<&USBDevice>`
pub fn print_bus_grouped(
bus_devices: Vec<(&USBBus, Vec<&USBDevice>)>,
settings: &PrintSettings,
) {
let bb = settings.bus_blocks.to_owned().unwrap_or(
Block::<BusBlocks, USBBus>::default_blocks(
pub fn print_bus_grouped(bus_devices: Vec<(&USBBus, Vec<&USBDevice>)>, settings: &PrintSettings) {
let bb = settings
.bus_blocks
.to_owned()
.unwrap_or(Block::<BusBlocks, USBBus>::default_blocks(
settings.verbosity >= MAX_VERBOSITY || settings.more,
),
);
));
let mut pad: HashMap<BusBlocks, usize> = if !settings.no_padding {
let buses: Vec<&USBBus> = bus_devices.iter().map(|bd| bd.0).collect();
BusBlocks::generate_padding(&buses)
Expand Down Expand Up @@ -2067,8 +2050,7 @@ pub fn print_endpoints(

// maybe should just do once at start of bus
if settings.headings && i == 0 {
let heading =
render_heading(blocks, &pad, max_variable_string_len).join(" ");
let heading = render_heading(blocks, &pad, max_variable_string_len).join(" ");
println!("{} {}", prefix, heading.bold().underline());
}

Expand All @@ -2080,8 +2062,7 @@ pub fn print_endpoints(
);
} else {
if settings.headings && i == 0 {
let heading =
render_heading(blocks, &pad, max_variable_string_len).join(" ");
let heading = render_heading(blocks, &pad, max_variable_string_len).join(" ");
println!("{:spaces$}{}", "", heading.bold().underline(), spaces = 6);
}

Expand Down Expand Up @@ -2181,8 +2162,7 @@ pub fn print_interfaces(

// maybe should just do once at start of bus
if settings.headings && i == 0 {
let heading =
render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
let heading = render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
println!("{} {}", prefix, heading.bold().underline());
}

Expand All @@ -2196,8 +2176,7 @@ pub fn print_interfaces(
);
} else {
if settings.headings && i == 0 {
let heading =
render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
let heading = render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
println!("{:spaces$}{}", "", heading.bold().underline(), spaces = 4);
}

Expand Down Expand Up @@ -2312,8 +2291,7 @@ pub fn print_configurations(

// maybe should just do once at start of bus
if settings.headings && i == 0 {
let heading =
render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
let heading = render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
println!("{} {}", prefix, heading.bold().underline());
}

Expand All @@ -2326,8 +2304,7 @@ pub fn print_configurations(
);
} else {
if settings.headings && i == 0 {
let heading =
render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
let heading = render_heading(blocks.0, &pad, max_variable_string_len).join(" ");
println!("{:spaces$}{}", "", heading.bold().underline(), spaces = 2);
}

Expand Down Expand Up @@ -2487,12 +2464,13 @@ pub fn print_devices(

/// Print SPUSBDataType
pub fn print_sp_usb(sp_usb: &SPUSBDataType, settings: &PrintSettings) {
let mut bb = settings.bus_blocks.to_owned().unwrap_or(Block::<
BusBlocks,
USBBus,
>::default_blocks(
settings.verbosity >= MAX_VERBOSITY || settings.more,
));
let mut bb =
settings
.bus_blocks
.to_owned()
.unwrap_or(Block::<BusBlocks, USBBus>::default_blocks(
settings.verbosity >= MAX_VERBOSITY || settings.more,
));
let mut db = settings.device_blocks.to_owned().unwrap_or(
if settings.verbosity >= MAX_VERBOSITY || settings.more {
DeviceBlocks::default_blocks(true)
Expand Down Expand Up @@ -2590,8 +2568,7 @@ pub fn print_sp_usb(sp_usb: &SPUSBDataType, settings: &PrintSettings) {
}

if settings.headings {
let heading =
render_heading(&bb, &pad, max_variable_string_len).join(" ");
let heading = render_heading(&bb, &pad, max_variable_string_len).join(" ");
// 2 spaces for bus start icon and space to info
println!("{:>spaces$}{}", "", heading.bold().underline(), spaces = 2);
}
Expand Down Expand Up @@ -2646,18 +2623,15 @@ pub fn mask_serial(device: &mut USBDevice, hide: &MaskSerial, recursive: bool) {
}

if recursive {
device.devices.iter_mut().for_each(|dd| {
dd.iter_mut().for_each(|d| mask_serial(d, hide, recursive))
});
device
.devices
.iter_mut()
.for_each(|dd| dd.iter_mut().for_each(|d| mask_serial(d, hide, recursive)));
}
}

/// Main cyme bin prepare for printing function - changes mutable `sp_usb` with requested `filter` and sort in `settings`
pub fn prepare(
sp_usb: &mut SPUSBDataType,
filter: Option<USBFilter>,
settings: &PrintSettings,
) {
pub fn prepare(sp_usb: &mut SPUSBDataType, filter: Option<USBFilter>, settings: &PrintSettings) {
// if not printing tree, hard flatten now before filtering as filter will retain non-matching parents with matching devices in tree
// but only do it if there is a filter, grouping by bus (which uses tree print without tree...) or json
// flattening now will also mean hubs will be removed when listing if `hide_hubs` because they will appear empty
Expand Down
Loading

0 comments on commit 3e1851e

Please sign in to comment.