Skip to main content

greentic_operator/demo/
pack_resolve.rs

1use std::path::{Path, PathBuf};
2
3use anyhow::{Context, Result, anyhow};
4
5use crate::domains;
6
7#[derive(Debug, Clone)]
8pub struct DemoPack {
9    pub pack_id: String,
10    pub pack_path: PathBuf,
11    pub entry_flows: Vec<String>,
12    pub default_flow_source: EntryFlowSource,
13}
14
15#[derive(Clone, Copy, Debug)]
16pub enum EntryFlowSource {
17    MetaEntryFlows,
18    FlowsList,
19}
20
21impl EntryFlowSource {
22    fn description(self) -> &'static str {
23        match self {
24            EntryFlowSource::MetaEntryFlows => "meta.entry_flows",
25            EntryFlowSource::FlowsList => "manifest.flows[*].id/entrypoints",
26        }
27    }
28}
29
30impl DemoPack {
31    pub fn select_flow(&self, requested: Option<&str>) -> Result<String> {
32        if self.entry_flows.is_empty() {
33            return Err(anyhow!(
34                "default flow not declared ({}) and no flows available; available flows: []",
35                self.default_flow_source.description()
36            ));
37        }
38        if let Some(flow) = requested {
39            if self.entry_flows.iter().any(|candidate| candidate == flow) {
40                return Ok(flow.to_string());
41            }
42            return Err(anyhow!(
43                "flow `{flow}` not declared via {}; available flows: {}",
44                self.default_flow_source.description(),
45                self.entry_flows.join(", ")
46            ));
47        }
48        Ok(self.entry_flows[0].clone())
49    }
50}
51
52pub fn resolve_pack(packs_dir: &Path, pack_name: &str) -> Result<DemoPack> {
53    let pack_path = packs_dir.join(pack_name);
54    if !pack_path.exists() {
55        return Err(anyhow!(
56            "pack {pack_name} not found under {}",
57            packs_dir.display()
58        ));
59    }
60    let meta = domains::read_pack_meta(&pack_path)
61        .with_context(|| format!("failed to read manifest for pack {}", pack_path.display()))?;
62    Ok(DemoPack {
63        pack_id: meta.pack_id.clone(),
64        pack_path,
65        entry_flows: meta.entry_flows.clone(),
66        default_flow_source: EntryFlowSource::MetaEntryFlows,
67    })
68}