1use std::time::Duration;
2
3use anyhow::Result;
4use serde::Serialize;
5use tracing::info;
6
7use viva_gige::nic::IfaceSelector;
8
9use crate::common;
10
11#[derive(Serialize)]
12struct DeviceEntry {
13 index: usize,
14 ip: String,
15 mac: String,
16 manufacturer: Option<String>,
17 model: Option<String>,
18}
19
20pub async fn run(timeout_ms: u64, iface: Option<IfaceSelector>, json: bool) -> Result<()> {
21 let timeout = Duration::from_millis(timeout_ms);
22 let devices = common::discover_devices(timeout, iface.as_ref()).await?;
23 info!(count = devices.len(), "discovered cameras");
24
25 if json {
26 let entries: Vec<DeviceEntry> = devices
27 .iter()
28 .enumerate()
29 .map(|(idx, dev)| DeviceEntry {
30 index: idx,
31 ip: dev.ip.to_string(),
32 mac: common::format_mac(&dev.mac),
33 manufacturer: dev.manufacturer.clone(),
34 model: dev.model.clone(),
35 })
36 .collect();
37 common::print_json(&entries)?;
38 return Ok(());
39 }
40
41 if devices.is_empty() {
42 println!("No cameras discovered.");
43 return Ok(());
44 }
45
46 println!(
47 "{:<6} {:<16} {:<18} {:<20} Model",
48 "INDEX", "IP", "MAC", "Manufacturer"
49 );
50 for (idx, dev) in devices.iter().enumerate() {
51 println!(
52 "{idx:<6} {:<16} {:<18} {:<20} {}",
53 dev.ip,
54 common::format_mac(&dev.mac),
55 dev.manufacturer.as_deref().unwrap_or("-"),
56 dev.model.as_deref().unwrap_or("-"),
57 );
58 }
59
60 Ok(())
61}