i want that filter table bs to be Going Away. restful? idk. we speak Devices now.

This commit is contained in:
lda
2026-04-14 01:07:22 +07:00 Unverified
parent 834a56d439
commit 42cdc720a3
9 changed files with 43 additions and 87 deletions
+2 -1
View File
@@ -141,6 +141,7 @@ pub async fn run(cli: Cli) -> Result<()> {
Command::Status(args) => {
let as_json = args.json;
let query = status_args_to_query(args);
let selected_name = query.name.clone();
debug!(?query, json = as_json, "dispatching status command");
let status = if query.name.is_some()
&& query.filter.ips.is_empty()
@@ -155,7 +156,7 @@ pub async fn run(cli: Cli) -> Result<()> {
if as_json {
println!("{}", serde_json::to_string_pretty(&status)?);
} else {
if let Some(name) = &status.name {
if let Some(name) = &selected_name {
println!("name: {name}");
}
println!("{}", table::render_status_table(&status));
+26 -8
View File
@@ -1,16 +1,34 @@
use chrono::{DateTime, Local};
use comfy_table::{Cell, ContentArrangement, Table, presets::UTF8_FULL};
use wakey_core::{DhcpLeaseWithState, InterfaceSummary, Status, WakeResult};
use wakey_core::{DeviceInventory, DhcpLeaseWithState, InterfaceSummary, WakeResult};
pub fn render_status_table(status: &Status<wakey_core::NeighborEntry>) -> Table {
pub fn render_status_table(status: &DeviceInventory) -> Table {
let mut table = base_table();
table.set_header(vec!["IP", "MAC", "Dev", "State"]);
for row in &status.table {
table.set_header(vec!["Name", "IP", "MAC", "Presence", "Interfaces"]);
for row in &status.devices {
table.add_row(vec![
Cell::new(row.ip.to_string()),
Cell::new(row.mac.map(|v| v.to_string()).unwrap_or_default()),
Cell::new(row.dev.clone().unwrap_or_default()),
Cell::new(row.state.to_string()),
Cell::new(
row.names
.first()
.cloned()
.unwrap_or_else(|| "(unnamed)".into()),
),
Cell::new(
row.ips
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(", "),
),
Cell::new(
row.macs
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(", "),
),
Cell::new(format!("{:?}", row.presence)),
Cell::new(row.interfaces.join(", ")),
]);
}
table
+4 -5
View File
@@ -2,11 +2,10 @@ pub mod service;
pub mod utils;
pub use service::{
StatusResponse, broadcast_wake_targets, device_to_status_rows, get_interface_summaries,
get_interface_summary, get_ips, get_leases, get_status, get_status_for_input, inventory,
leases_without_state, list_interfaces, merge_devices, query_to_device_query, resolve_devices,
resolve_query, resolve_selector, resolve_wake_targets, wake_explicit, wake_from_query,
wake_targets,
StatusResponse, broadcast_wake_targets, get_interface_summaries, get_interface_summary,
get_ips, get_leases, get_status, get_status_for_input, inventory, leases_without_state,
list_interfaces, merge_devices, query_to_device_query, resolve_devices, resolve_query,
resolve_selector, resolve_wake_targets, wake_explicit, wake_from_query, wake_targets,
};
#[cfg(test)]
+1 -1
View File
@@ -9,7 +9,7 @@ pub use interfaces::{get_interface_summaries, get_interface_summary, get_ips, li
pub use inventory::{inventory, merge_devices, resolve_devices};
pub use leases::{get_leases, leases_without_state};
pub use query::{query_to_device_query, resolve_query, resolve_selector};
pub use status::{StatusResponse, device_to_status_rows, get_status, get_status_for_input};
pub use status::{StatusResponse, get_status, get_status_for_input};
pub use wake::{
broadcast_wake_targets, resolve_wake_targets, wake_explicit, wake_from_query, wake_targets,
};
+7 -54
View File
@@ -1,35 +1,19 @@
use anyhow::Result;
use tracing::{debug, instrument};
use wakey_core::{Device, DeviceQuery, NeighborEntry, Presence, Status};
use wakey_core::{DeviceInventory, DeviceQuery};
use crate::service::inventory::inventory;
use crate::service::query::resolve_query;
/// Service status payload, still expressed in terms of legacy neighbor rows.
pub type StatusResponse = Status<NeighborEntry>;
/// Service status payload expressed in terms of merged device inventory.
pub type StatusResponse = DeviceInventory;
/// Return status rows derived from the merged device inventory.
///
/// This keeps the old status response shape alive while the underlying model is
/// increasingly device-centered.
/// Return status payload from merged device inventory.
#[instrument(skip_all, fields(name = ?query.name))]
pub async fn get_status(query: DeviceQuery) -> Result<StatusResponse> {
let inventory = inventory(query.clone()).await?;
let table: Vec<NeighborEntry> = inventory
.devices
.iter()
.flat_map(device_to_status_rows)
.collect();
debug!(
rows = table.len(),
devices = inventory.devices.len(),
"built status response"
);
Ok(Status {
name: query.name,
table,
filters: query.filter,
})
let inventory = inventory(query).await?;
debug!(devices = inventory.devices.len(), "built status response");
Ok(inventory)
}
/// Convenience wrapper around [`get_status`] for free-form user input.
@@ -38,34 +22,3 @@ pub async fn get_status_for_input(input: impl Into<String>) -> Result<StatusResp
let query = resolve_query(input).await?;
get_status(query).await
}
/// Project a device aggregate back into legacy status rows.
///
/// If the device already has neighbor rows they are reused directly; otherwise a
/// fallback row is synthesized from the best available device data.
pub fn device_to_status_rows(device: &Device) -> Vec<NeighborEntry> {
if !device.neighbors.is_empty() {
return device.neighbors.clone();
}
let fallback_mac = device.macs.first().copied();
let fallback_dev = device.interfaces.first().cloned();
let fallback_state = match device.presence {
Presence::Online => wakey_core::NeighborState::Reachable,
Presence::LikelyOnline => wakey_core::NeighborState::Stale,
Presence::Offline => wakey_core::NeighborState::Failed,
Presence::Unknown => wakey_core::NeighborState::None,
};
device
.ips
.iter()
.copied()
.map(|ip| NeighborEntry {
ip,
dev: fallback_dev.clone(),
mac: fallback_mac,
state: fallback_state,
})
.collect()
}