use kdl::KdlNode;
use crate::bus::{BusModule, response};
use crate::telemetry;
pub struct TelemetryModule;
impl TelemetryModule {
fn command_node<'a>(
module_node: &'a KdlNode,
command_nodes: &[&'a KdlNode],
) -> Option<&'a KdlNode> {
if let Some(cmd) = command_nodes.first() {
return Some(cmd);
}
module_node.children()?.nodes().first()
}
}
impl BusModule for TelemetryModule {
fn name(&self) -> &'static str {
"telemetry"
}
fn handle(&self, module_node: &KdlNode, command_nodes: &[&KdlNode]) -> String {
let Some(cmd) = Self::command_node(module_node, command_nodes) else {
return response::err("telemetry commands: status, set-level \"…\"");
};
match cmd.name().value() {
"status" => {
let rust_log = telemetry::current_filter_directive();
format!("status rust_log=\"{rust_log}\"")
}
"set-level" => {
let Some(level) = cmd.get("level").and_then(|v| v.as_string()) else {
return response::err(
"set-level requires level=\"info\" (or trace, debug, warn, error)",
);
};
match telemetry::set_filter_directive(level) {
Ok(()) => response::ok("level-updated"),
Err(e) => response::err(&e),
}
}
other => response::err(&format!("unknown telemetry command: {other}")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use kdl::KdlDocument;
#[test]
fn status_reports_filter() {
let doc: KdlDocument = "telemetry {\n status\n}".parse().unwrap();
let node = doc.nodes().first().unwrap();
let body = TelemetryModule.handle(node, &[]);
assert!(body.contains("rust_log="));
}
}