Skip to main content

liminal_server/services/site/
topology.rs

1//! Construction stations project one consistent record and trial snapshot.
2
3use super::super::{Lifecycle, ServiceState};
4use super::SiteError;
5use serde_json::{Value, json};
6
7impl Lifecycle {
8    /// Returns every construction service with its contracts, builder and plan.
9    ///
10    /// # Errors
11    /// The registry is poisoned or a record cannot be encoded.
12    pub fn site_stations(&self, device: &str) -> Result<Vec<Value>, SiteError> {
13        let registry = self.lock()?;
14        registry.records.values().filter(|record| record.purpose.is_some()).map(|record| {
15            let trial = registry.trials.get(&record.id).and_then(|trials| trials.iter().find(|(_, trial)| trial.live).map(|(connection, _)| *connection));
16            let state = match record.state {
17                ServiceState::Building if trial.is_some() => "trial",
18                ServiceState::Building => "building", ServiceState::Asleep => "asleep",
19                ServiceState::Live => "live", ServiceState::Held => "held", ServiceState::Retired => "retired",
20            };
21            let contracts: Vec<_> = record.contracts.iter().map(|(subject, contract)| json!({
22                "subject":subject,"input_schema_json":contract.input_schema_json,
23                "output_schema_json":contract.output_schema_json})).collect();
24            let mut station = json!({"id":format!("services.{}",record.name),"service":record.id,"name":record.name,"device":device,
25                "kind":"service","state":state,"subjects":record.subjects,
26                "purpose":record.purpose,"contracts":contracts,
27                "plan":super::super::plan::current_value(&record.plan),
28                "progress":{"done":record.plan.steps.iter().filter(|step| step.status == super::super::plan::StepStatus::Done).count(),
29                    "total":record.plan.steps.len()}, "transitions":record.transitions});
30            if let Some(builder) = &record.builder { station["builder"] = builder.clone().into(); }
31            if let Some(trial) = trial { station["trial_connection"] = trial.into(); }
32            Ok(station)
33        }).collect()
34    }
35}