liminal-server 0.25.4

Standalone server for the liminal messaging bus
Documentation
//! Construction stations project one consistent record and trial snapshot.

use super::super::{Lifecycle, ServiceState};
use super::SiteError;
use serde_json::{Value, json};

impl Lifecycle {
    /// Returns every construction service with its contracts, builder and plan.
    ///
    /// # Errors
    /// The registry is poisoned or a record cannot be encoded.
    pub fn site_stations(&self, device: &str) -> Result<Vec<Value>, SiteError> {
        let registry = self.lock()?;
        registry.records.values().filter(|record| record.purpose.is_some()).map(|record| {
            let trial = registry.trials.get(&record.id).and_then(|trials| trials.iter().find(|(_, trial)| trial.live).map(|(connection, _)| *connection));
            let state = match record.state {
                ServiceState::Building if trial.is_some() => "trial",
                ServiceState::Building => "building", ServiceState::Asleep => "asleep",
                ServiceState::Live => "live", ServiceState::Held => "held", ServiceState::Retired => "retired",
            };
            let contracts: Vec<_> = record.contracts.iter().map(|(subject, contract)| json!({
                "subject":subject,"input_schema_json":contract.input_schema_json,
                "output_schema_json":contract.output_schema_json})).collect();
            let mut station = json!({"id":format!("services.{}",record.name),"service":record.id,"name":record.name,"device":device,
                "kind":"service","state":state,"subjects":record.subjects,
                "purpose":record.purpose,"contracts":contracts,
                "plan":super::super::plan::current_value(&record.plan),
                "progress":{"done":record.plan.steps.iter().filter(|step| step.status == super::super::plan::StepStatus::Done).count(),
                    "total":record.plan.steps.len()}, "transitions":record.transitions});
            if let Some(builder) = &record.builder { station["builder"] = builder.clone().into(); }
            if let Some(trial) = trial { station["trial_connection"] = trial.into(); }
            Ok(station)
        }).collect()
    }
}