doc sweep!

This commit is contained in:
lda
2026-04-06 05:43:37 +07:00 Unverified
parent 67aa50ec5c
commit 79a6157a3a
22 changed files with 188 additions and 23 deletions
+6
View File
@@ -1,14 +1,19 @@
use anyhow::Result;
use wakey_core::InterfaceSummary;
/// Return interface names only.
///
/// This is the old, lightweight interface listing surface kept for compatibility.
pub async fn list_interfaces() -> Result<Vec<String>> {
Ok(wakey_linux::devices::devs_sorted().await)
}
/// Return condensed interface summaries useful for CLI and wake routing.
pub async fn get_interface_summaries() -> Result<Vec<InterfaceSummary>> {
wakey_linux::devices::list_interface_summaries().await
}
/// Return one named interface summary when present.
pub async fn get_interface_summary(name: &str) -> Result<Option<InterfaceSummary>> {
Ok(get_interface_summaries()
.await?
@@ -16,6 +21,7 @@ pub async fn get_interface_summary(name: &str) -> Result<Option<InterfaceSummary
.find(|iface| iface.ifname == name))
}
/// Resolve a hostname through the local resolver and collect all returned IPs.
pub async fn get_ips(name: impl AsRef<str>) -> Result<Vec<std::net::IpAddr>> {
Ok(wakey_linux::devices::get_ips(name.as_ref())
.await?
+10
View File
@@ -6,11 +6,17 @@ use wakey_core::{
use crate::service::leases::get_leases;
use crate::service::query::resolve_query;
/// Resolve free-form input and return merged devices rather than raw source rows.
pub async fn resolve_devices(input: impl Into<String>) -> Result<Vec<Device>> {
let query = resolve_query(input).await?;
inventory(query).await.map(|inventory| inventory.devices)
}
/// Build a merged device inventory from neighbor-table and DHCP-lease sources.
///
/// This is the current center of gravity for the service layer. Higher-level
/// status and wake flows should prefer deriving from inventory rather than
/// directly from raw Linux source rows.
pub async fn inventory(query: DeviceQuery) -> Result<DeviceInventory> {
let neighbors = wakey_linux::devices::query_status(&query).await?;
let leases = get_leases(wakey_core::LeaseQuery {
@@ -22,6 +28,10 @@ pub async fn inventory(query: DeviceQuery) -> Result<DeviceInventory> {
})
}
/// Merge raw neighbor entries and DHCP leases into device aggregates.
///
/// Identity is currently MAC-first, with an IP-based fallback when a neighbor
/// row does not include a MAC address.
pub fn merge_devices(
neighbors: Vec<NeighborEntry>,
leases: Vec<DhcpLeaseWithState>,
+2
View File
@@ -1,6 +1,7 @@
use anyhow::{Context, Result};
use wakey_core::{DhcpLease, DhcpLeaseWithState, LeaseQuery};
/// Read DHCP leases and optionally enrich them with current neighbor-state data.
pub async fn get_leases(query: LeaseQuery) -> Result<Vec<DhcpLeaseWithState>> {
let leases = wakey_linux::dhcp::read_dhcp_leases_with_names()
.await
@@ -12,6 +13,7 @@ pub async fn get_leases(query: LeaseQuery) -> Result<Vec<DhcpLeaseWithState>> {
}
}
/// Wrap raw DHCP leases in the current service output shape without neighbor state.
pub fn leases_without_state(leases: Vec<DhcpLease>) -> Vec<DhcpLeaseWithState> {
leases
.into_iter()
+12
View File
@@ -1,10 +1,18 @@
use anyhow::Result;
use wakey_core::{DeviceFilters, DeviceQuery, Query, QueryInput};
/// Resolve free-form user input into the legacy `DeviceQuery` filter shape.
///
/// This is the compatibility entrypoint used by CLI and HTTP paths that still
/// speak in terms of `DeviceQuery`.
pub async fn resolve_query(input: impl Into<String>) -> Result<DeviceQuery> {
query_to_device_query(resolve_selector(input).await?)
}
/// Classify one piece of free-form user input into a typed selector.
///
/// The Linux adapter decides whether the input looks like an IP address, MAC,
/// interface name, neighbor state, or plain text.
pub async fn resolve_selector(input: impl Into<String>) -> Result<Query> {
Ok(
match wakey_linux::devices::classify_query(input.into()).await {
@@ -17,6 +25,10 @@ pub async fn resolve_selector(input: impl Into<String>) -> Result<Query> {
)
}
/// Convert the newer selector-oriented `Query` model into a `DeviceQuery`.
///
/// This keeps the old filter-based service and HTTP surfaces working while the
/// internals migrate toward selector- and device-oriented APIs.
pub fn query_to_device_query(query: Query) -> Result<DeviceQuery> {
Ok(match query {
Query::Ip(ip_addr) => DeviceQuery {
+10
View File
@@ -4,8 +4,13 @@ use wakey_core::{Device, DeviceQuery, NeighborEntry, Presence, Status};
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>;
/// 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.
pub async fn get_status(query: DeviceQuery) -> Result<StatusResponse> {
let inventory = inventory(query.clone()).await?;
let table = inventory
@@ -20,11 +25,16 @@ pub async fn get_status(query: DeviceQuery) -> Result<StatusResponse> {
})
}
/// Convenience wrapper around [`get_status`] for free-form user input.
pub async fn get_status_for_input(input: impl Into<String>) -> Result<StatusResponse> {
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();
+10
View File
@@ -6,6 +6,7 @@ use wakey_core::{WakeResult, WakeTarget};
use crate::service::interfaces::get_interface_summaries;
use crate::service::inventory::resolve_devices;
/// Send Wake-on-LAN packets for already-concrete wake targets.
pub async fn wake_targets(targets: Vec<WakeTarget>) -> Result<WakeResult> {
let result = wakey_linux::wake::wake_many(targets)
.await
@@ -13,11 +14,15 @@ pub async fn wake_targets(targets: Vec<WakeTarget>) -> Result<WakeResult> {
Ok(WakeResult { result })
}
/// Resolve free-form input into wake targets and send the packets.
pub async fn wake_from_query(input: impl Into<String>) -> Result<WakeResult> {
let targets = resolve_wake_targets(input).await?;
wake_targets(targets).await
}
/// Build broadcast wake targets for every broadcast-capable interface.
///
/// This is used by explicit manual wake mode when only a MAC address is supplied.
pub async fn broadcast_wake_targets(mac: MacAddr) -> Result<Vec<WakeTarget>> {
Ok(get_interface_summaries()
.await?
@@ -31,6 +36,7 @@ pub async fn broadcast_wake_targets(mac: MacAddr) -> Result<Vec<WakeTarget>> {
.collect())
}
/// Wake a device explicitly by MAC, optionally targeting a specific IP/broadcast.
pub async fn wake_explicit(mac: MacAddr, ip: Option<IpAddr>) -> Result<WakeResult> {
let targets = match ip {
Some(ip) => vec![WakeTarget {
@@ -42,6 +48,10 @@ pub async fn wake_explicit(mac: MacAddr, ip: Option<IpAddr>) -> Result<WakeResul
wake_targets(targets).await
}
/// Resolve free-form input into concrete wake targets.
///
/// The current resolution strategy fans out one wake target per resolved device IP,
/// using the first known MAC address for that device.
pub async fn resolve_wake_targets(input: impl Into<String>) -> Result<Vec<WakeTarget>> {
let devices = resolve_devices(input).await?;
Ok(devices