liminal-server 0.24.5

Standalone server for the liminal messaging bus
Documentation
//! The line follows the live serving registration, including its replacement and close.

use super::{Line, LineKind, LineLife, LineState, TopologyModel, is_console_subject};
use std::collections::BTreeMap;

impl TopologyModel {
    pub(super) fn all_lines(&self) -> Vec<Line> {
        let mut lines: BTreeMap<_, _> = self
            .lines
            .iter()
            .map(|(name, (life, state))| {
                (
                    name.clone(),
                    Line {
                        id: name.clone(),
                        kind: LineKind::Stream,
                        life: *life,
                        state: *state,
                        stops: self.stops(name, *life),
                    },
                )
            })
            .collect();
        lines.extend(self.service_lines());
        lines.into_values().collect()
    }

    pub(super) fn service_lines(&self) -> BTreeMap<String, Line> {
        let mut lines = BTreeMap::new();
        for subject in &self.stations {
            if is_console_subject(subject) || self.reserved(subject).is_some() {
                continue;
            }
            lines.insert(
                subject.clone(),
                self.call_line(subject, vec![subject.clone()]),
            );
        }
        for worker in self.workers.values() {
            if self.reserved(&worker.identity).is_some() {
                continue;
            }
            for subject in &worker.subjects {
                if is_console_subject(subject) {
                    continue;
                }
                let line = lines
                    .entry(subject.clone())
                    .or_insert_with(|| self.call_line(subject, vec![]));
                if !line.stops.contains(&worker.identity) {
                    line.stops.push(worker.identity.clone());
                }
            }
        }
        lines
    }

    fn call_line(&self, subject: &str, stations: Vec<String>) -> Line {
        let mut stops = vec![self.this.id.clone()];
        stops.extend(stations);
        Line {
            id: subject.to_owned(),
            kind: LineKind::Call,
            life: LineLife::Passing,
            state: LineState::Live,
            stops,
        }
    }

    pub(crate) fn serving_station(&self, subject: &str) -> Option<String> {
        self.stations.contains(subject).then(|| subject.to_owned())
    }
}