robotrt-middleware-core 0.1.0-beta.2

RobotRT modular robotics runtime and middleware components.
Documentation
use std::time::Instant;

use super::SimpleDiscovery;
use super::state_helpers::is_name_active;
use super::types::{DiscoveryEndpoint, DiscoveryEntry};

impl SimpleDiscovery {
    pub fn topic_entries(&self) -> Vec<DiscoveryEntry> {
        let now = Instant::now();
        let mut entries: Vec<DiscoveryEntry> = self
            .topics
            .iter()
            .filter(|name| self.is_topic_active(name, now))
            .map(|name| DiscoveryEntry {
                name: name.clone(),
                labels: self.labels.get(name).cloned().unwrap_or_default(),
            })
            .collect();
        entries.sort_by(|a, b| a.name.cmp(&b.name));
        entries
    }

    pub fn service_entries(&self) -> Vec<DiscoveryEntry> {
        let now = Instant::now();
        let mut entries: Vec<DiscoveryEntry> = self
            .services
            .iter()
            .filter(|name| self.is_service_active(name, now))
            .map(|name| DiscoveryEntry {
                name: name.clone(),
                labels: self.labels.get(name).cloned().unwrap_or_default(),
            })
            .collect();
        entries.sort_by(|a, b| a.name.cmp(&b.name));
        entries
    }

    pub fn mission_entries(&self) -> Vec<DiscoveryEntry> {
        let now = Instant::now();
        let mut entries: Vec<DiscoveryEntry> = self
            .missions
            .iter()
            .filter(|name| self.is_mission_active(name, now))
            .map(|name| DiscoveryEntry {
                name: name.clone(),
                labels: self.labels.get(name).cloned().unwrap_or_default(),
            })
            .collect();
        entries.sort_by(|a, b| a.name.cmp(&b.name));
        entries
    }

    pub fn find_topic(&self, name: &str) -> Option<DiscoveryEntry> {
        if !self.is_topic_active(name, Instant::now()) {
            return None;
        }
        self.topics.get(name).map(|topic| DiscoveryEntry {
            name: topic.clone(),
            labels: self.labels.get(topic).cloned().unwrap_or_default(),
        })
    }

    pub fn find_endpoint(&self, name: &str) -> Option<DiscoveryEndpoint> {
        if !self.is_endpoint_active(name, Instant::now()) {
            return None;
        }
        self.endpoints.get(name).map(|endpoint| DiscoveryEndpoint {
            name: name.to_string(),
            endpoint: endpoint.clone(),
        })
    }

    pub fn endpoint_entries(&self) -> Vec<DiscoveryEndpoint> {
        let now = Instant::now();
        let mut entries: Vec<DiscoveryEndpoint> = self
            .endpoints
            .iter()
            .filter(|(name, _)| self.is_endpoint_active(name, now))
            .map(|(name, endpoint)| DiscoveryEndpoint {
                name: name.clone(),
                endpoint: endpoint.clone(),
            })
            .collect();
        entries.sort_by(|a, b| a.name.cmp(&b.name));
        entries
    }

    pub(super) fn is_topic_active(&self, name: &str, now: Instant) -> bool {
        self.topics.contains(name) && is_name_active(&self.topic_state, name, now)
    }

    pub(super) fn is_service_active(&self, name: &str, now: Instant) -> bool {
        self.services.contains(name) && is_name_active(&self.service_state, name, now)
    }

    pub(super) fn is_mission_active(&self, name: &str, now: Instant) -> bool {
        self.missions.contains(name) && is_name_active(&self.mission_state, name, now)
    }

    pub(super) fn is_endpoint_active(&self, name: &str, now: Instant) -> bool {
        self.endpoints.contains_key(name) && is_name_active(&self.endpoint_state, name, now)
    }

    pub(super) fn remove_labels_if_unused(&mut self, key: &str) {
        if self.topics.contains(key)
            || self.services.contains(key)
            || self.missions.contains(key)
            || self.endpoints.contains_key(key)
        {
            return;
        }
        self.labels.remove(key);
    }
}