Skip to main content

viva_camctl/
cmd_list.rs

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}