robotrt-middleware-core 0.1.0-beta.2

RobotRT modular robotics runtime and middleware components.
Documentation
use std::net::UdpSocket;
use std::path::Path;
use std::time::Duration;

use super::super::SimpleDiscovery;

impl SimpleDiscovery {
    /// Load static discovery directives from an in-memory string payload.
    pub fn load_static_payload(&mut self, payload: &str) -> Result<usize, String> {
        self.load_static_lines(payload.lines())
    }

    /// Broadcast current static discovery payload over UDP in one datagram.
    pub fn broadcast_static_payload_udp(&self, destination: &str) -> Result<usize, String> {
        let socket = UdpSocket::bind("0.0.0.0:0")
            .map_err(|e| format!("bind udp broadcaster failed: {e}"))?;
        socket
            .set_broadcast(true)
            .map_err(|e| format!("enable broadcast failed: {e}"))?;
        let payload = self.dump_static_payload();
        socket
            .send_to(payload.as_bytes(), destination)
            .map_err(|e| format!("udp broadcast failed: {e}"))
    }

    /// Receive one UDP discovery payload and merge it into this registry.
    pub fn receive_static_payload_udp(
        &mut self,
        bind_addr: &str,
        timeout: Duration,
    ) -> Result<usize, String> {
        let socket =
            UdpSocket::bind(bind_addr).map_err(|e| format!("bind udp receiver failed: {e}"))?;
        socket
            .set_read_timeout(Some(timeout))
            .map_err(|e| format!("set read timeout failed: {e}"))?;

        let mut buf = [0u8; 65_535];
        let (size, _) = socket
            .recv_from(&mut buf)
            .map_err(|e| format!("recv udp discovery payload failed: {e}"))?;
        let payload = std::str::from_utf8(&buf[..size])
            .map_err(|e| format!("discovery payload is not utf-8: {e}"))?;
        self.load_static_payload(payload)
    }

    pub fn load_static_file(&mut self, path: impl AsRef<Path>) -> Result<usize, String> {
        let content = std::fs::read_to_string(path.as_ref())
            .map_err(|e| format!("read discovery file failed: {e}"))?;
        self.load_static_lines(content.lines())
    }
}