ig idek chat transformed my code too good it turns ahh now.
This commit is contained in:
+68
-1
@@ -1,7 +1,8 @@
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use wakey_core::parse::mac;
|
use wakey_core::parse::mac;
|
||||||
use wakey_core::{
|
use wakey_core::{
|
||||||
DeviceFilters, DhcpLeaseWithState, NeighborEntry, Status, WakeResult, WakeTargetResult,
|
Device, DeviceFilters, DeviceInventory, DhcpLeaseWithState, NeighborEntry, Status, WakeResult,
|
||||||
|
WakeTargetResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
@@ -50,6 +51,23 @@ pub fn legacy_status_from_domain(status: Status<NeighborEntry>) -> LegacyStatusR
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn legacy_status_from_inventory(
|
||||||
|
inventory: DeviceInventory,
|
||||||
|
name: Option<String>,
|
||||||
|
filters: DeviceFilters,
|
||||||
|
) -> LegacyStatusResponse {
|
||||||
|
let table = inventory
|
||||||
|
.devices
|
||||||
|
.into_iter()
|
||||||
|
.flat_map(legacy_status_rows_from_device)
|
||||||
|
.collect();
|
||||||
|
LegacyStatusResponse {
|
||||||
|
name,
|
||||||
|
table,
|
||||||
|
filters,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn legacy_status_row(row: NeighborEntry) -> LegacyStatusRow {
|
pub fn legacy_status_row(row: NeighborEntry) -> LegacyStatusRow {
|
||||||
LegacyStatusRow {
|
LegacyStatusRow {
|
||||||
ip: row.ip,
|
ip: row.ip,
|
||||||
@@ -59,6 +77,36 @@ pub fn legacy_status_row(row: NeighborEntry) -> LegacyStatusRow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn legacy_status_rows_from_device(device: Device) -> Vec<LegacyStatusRow> {
|
||||||
|
if !device.neighbors.is_empty() {
|
||||||
|
return device
|
||||||
|
.neighbors
|
||||||
|
.into_iter()
|
||||||
|
.map(legacy_status_row)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
let fallback_mac = device.macs.first().copied();
|
||||||
|
let fallback_dev = device.interfaces.first().cloned();
|
||||||
|
let fallback_state = match device.presence {
|
||||||
|
wakey_core::Presence::Online => wakey_core::NeighborState::Reachable,
|
||||||
|
wakey_core::Presence::LikelyOnline => wakey_core::NeighborState::Stale,
|
||||||
|
wakey_core::Presence::Offline => wakey_core::NeighborState::Failed,
|
||||||
|
wakey_core::Presence::Unknown => wakey_core::NeighborState::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
device
|
||||||
|
.ips
|
||||||
|
.into_iter()
|
||||||
|
.map(|ip| LegacyStatusRow {
|
||||||
|
ip,
|
||||||
|
dev: fallback_dev.clone(),
|
||||||
|
mac: fallback_mac,
|
||||||
|
state: fallback_state,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn legacy_leases_from_domain(leases: Vec<DhcpLeaseWithState>) -> Vec<LegacyLeaseRow> {
|
pub fn legacy_leases_from_domain(leases: Vec<DhcpLeaseWithState>) -> Vec<LegacyLeaseRow> {
|
||||||
leases.into_iter().map(legacy_lease_row).collect()
|
leases.into_iter().map(legacy_lease_row).collect()
|
||||||
}
|
}
|
||||||
@@ -110,6 +158,25 @@ mod tests {
|
|||||||
assert_eq!(legacy.table[0].state, NeighborState::Reachable);
|
assert_eq!(legacy.table[0].state, NeighborState::Reachable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn maps_inventory_to_legacy_status_shape() {
|
||||||
|
let inventory = DeviceInventory {
|
||||||
|
devices: vec![Device::from_parts(
|
||||||
|
vec![NeighborEntry {
|
||||||
|
ip: IpAddr::V4(Ipv4Addr::new(192, 168, 1, 10)),
|
||||||
|
dev: Some("br-lan".into()),
|
||||||
|
mac: Some("aa:bb:cc:dd:ee:ff".parse().expect("mac")),
|
||||||
|
state: NeighborState::Reachable,
|
||||||
|
}],
|
||||||
|
vec![],
|
||||||
|
)],
|
||||||
|
};
|
||||||
|
let legacy = legacy_status_from_inventory(inventory, Some("pc".into()), DeviceFilters::default());
|
||||||
|
assert_eq!(legacy.name.as_deref(), Some("pc"));
|
||||||
|
assert_eq!(legacy.table.len(), 1);
|
||||||
|
assert_eq!(legacy.table[0].state, NeighborState::Reachable);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn maps_leases_to_legacy_shape() {
|
fn maps_leases_to_legacy_shape() {
|
||||||
let leases = vec![DhcpLeaseWithState {
|
let leases = vec![DhcpLeaseWithState {
|
||||||
|
|||||||
+35
-3
@@ -71,7 +71,12 @@ pub fn query_to_device_query(query: Query) -> Result<DeviceQuery> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_status(query: DeviceQuery) -> Result<StatusResponse> {
|
pub async fn get_status(query: DeviceQuery) -> Result<StatusResponse> {
|
||||||
let table = wakey_linux::devices::query_status(&query).await?;
|
let inventory = inventory(query.clone()).await?;
|
||||||
|
let table = inventory
|
||||||
|
.devices
|
||||||
|
.iter()
|
||||||
|
.flat_map(device_to_status_rows)
|
||||||
|
.collect();
|
||||||
Ok(Status {
|
Ok(Status {
|
||||||
name: query.name,
|
name: query.name,
|
||||||
table,
|
table,
|
||||||
@@ -123,13 +128,13 @@ pub async fn resolve_devices(input: impl Into<String>) -> Result<Vec<Device>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn inventory(query: DeviceQuery) -> Result<DeviceInventory> {
|
pub async fn inventory(query: DeviceQuery) -> Result<DeviceInventory> {
|
||||||
let status = get_status(query.clone()).await?;
|
let neighbors = wakey_linux::devices::query_status(&query).await?;
|
||||||
let leases = get_leases(LeaseQuery {
|
let leases = get_leases(LeaseQuery {
|
||||||
include_state: false,
|
include_state: false,
|
||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
Ok(DeviceInventory {
|
Ok(DeviceInventory {
|
||||||
devices: merge_devices(status.table, leases, &query),
|
devices: merge_devices(neighbors, leases, &query),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,6 +226,33 @@ const fn presence_rank(presence: Presence) -> u8 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn http_app(static_root: std::path::PathBuf) -> Router {
|
pub fn http_app(static_root: std::path::PathBuf) -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.nest("/api", route::api_router())
|
.nest("/api", route::api_router())
|
||||||
|
|||||||
+7
-3
@@ -4,10 +4,14 @@ use axum_extra::extract::Query;
|
|||||||
pub use wakey_core::{DeviceQuery, NamePath};
|
pub use wakey_core::{DeviceQuery, NamePath};
|
||||||
|
|
||||||
pub async fn get_status_json(Query(query): Query<DeviceQuery>) -> impl IntoResponse {
|
pub async fn get_status_json(Query(query): Query<DeviceQuery>) -> impl IntoResponse {
|
||||||
match crate::get_status(query).await {
|
match crate::inventory(query.clone()).await {
|
||||||
Ok(status) => (
|
Ok(inventory) => (
|
||||||
StatusCode::OK,
|
StatusCode::OK,
|
||||||
Json(crate::compat::legacy_status_from_domain(status)),
|
Json(crate::compat::legacy_status_from_inventory(
|
||||||
|
inventory,
|
||||||
|
query.name,
|
||||||
|
query.filter,
|
||||||
|
)),
|
||||||
)
|
)
|
||||||
.into_response(),
|
.into_response(),
|
||||||
Err(error) => ApiError {
|
Err(error) => ApiError {
|
||||||
|
|||||||
Reference in New Issue
Block a user