Consolidate backend scanner status, paging, and query-param duplication

Add ActiveStatusCell/PassiveStatusCell wrappers in the scanners common
module so the five per-scanner status.rs files reduce to a single static;
replace parse_parameter_bool/int/string with one generic parse_parameter
over FromStr; extract the shared LIMIT/OFFSET paging clause into
db::apply_paging; and drop a no-op for-loop in the ARP sender.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
rzuasti
2026-06-06 09:03:00 -04:00
co-authored by Claude Opus 4.8
parent c022e672d1
commit 8749ff33c1
27 changed files with 189 additions and 260 deletions
@@ -1,6 +1,8 @@
use crate::model::devices::Device;
use chrono::{DateTime, Utc};
use once_cell::sync::OnceCell;
use std::collections::HashSet;
use std::sync::Mutex;
/// Status state for the active (polling) scanners — ARP and SNMP. Each scanner owns its own
/// `OnceCell<Mutex<ActiveStatus>>` and delegates to these methods (see e.g.
@@ -67,6 +69,50 @@ impl ActiveStatus {
}
}
/// A lazily-initialised, mutex-guarded [`ActiveStatus`] owned by a single active scanner. Each
/// scanner declares one as a `static` and the API layer reads it back via [`get`](Self::get).
/// All methods are no-ops until [`init`](Self::init) is called (mirroring the previous
/// per-scanner `OnceCell` behaviour).
pub struct ActiveStatusCell(OnceCell<Mutex<ActiveStatus>>);
impl ActiveStatusCell {
pub const fn new() -> Self {
Self(OnceCell::new())
}
pub fn init(&self) {
self.0.set(Mutex::new(ActiveStatus::new())).ok();
}
pub fn set_running(&self) {
if let Some(m) = self.0.get() {
m.lock().unwrap().set_running();
}
}
pub fn set_waiting(&self, next_scan_at: DateTime<Utc>) {
if let Some(m) = self.0.get() {
m.lock().unwrap().set_waiting(next_scan_at);
}
}
pub fn record_scan(&self, devices: &[Device]) {
if let Some(m) = self.0.get() {
m.lock().unwrap().record_scan(devices);
}
}
pub fn get(&self) -> Option<ActiveSnapshot> {
self.0.get().map(|m| m.lock().unwrap().snapshot())
}
}
impl Default for ActiveStatusCell {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;