robotrt-cli 0.1.0-beta.2

RobotRT modular robotics runtime and middleware components.
use crate::helpers::{has_flag, option_value, parse_u64_option, resolve_runtime_endpoint_from_hint};
use crate::gateway::{
    STATUS_OP_RUNTIME, STATUS_SERVICE_NAME, StatusServiceResponse, build_request,
    make_udp_service_client, next_request_id, validate_response,
};

const DEFAULT_DAEMON_ENDPOINT: &str = "127.0.0.1:7588";

pub fn runtime_load(args: &[String]) -> Result<(), String> {
    let json = has_flag(args, "--json");

    let endpoint = resolve_runtime_endpoint_from_hint(
        args,
        option_value(args, "--endpoint"),
        DEFAULT_DAEMON_ENDPOINT,
    )?;
    let timeout_ms = parse_u64_option(args, "--timeout-ms", 1000)?;
    let client = make_udp_service_client(endpoint.clone(), timeout_ms)?;
    let request_id = next_request_id();
    let request = build_request(STATUS_OP_RUNTIME);
    let response: StatusServiceResponse = client
        .call_json(STATUS_SERVICE_NAME, request_id, &request)
        .map_err(|err| format!("runtime query to {endpoint} failed: {err}"))?;

    validate_response(&response, request_id, STATUS_OP_RUNTIME)?;
    let report = response.runtime.ok_or_else(|| {
        format!("runtime response from {endpoint} missing runtime payload")
    })?;

    if json {
        let payload = serde_json::to_string_pretty(&report)
            .map_err(|err| format!("serialize runtime report to json failed: {err}"))?;
        println!("{payload}");
    } else {
        println!("RobotRT Runtime Load");
        println!("source: remote:{endpoint}");
        println!(
            "queue_depth={:?} retransmit_drivers={:?} backpressure={:?}",
            report.queue_depth, report.retransmit_drivers, report.backpressure
        );
        println!(
            "health: status={} reason={}",
            report.health.status,
            report.health.reason.as_deref().unwrap_or("-")
        );
        println!("metrics={}", report.metrics.len());
    }

    Ok(())
}