greentic_flow/
registry.rs1use anyhow::Context;
2use serde::{Deserialize, Serialize};
3use std::{
4 collections::{HashMap, HashSet},
5 env, fs,
6 path::Path,
7};
8
9use crate::path_safety::normalize_under_root;
10
11#[derive(Clone, Debug, Serialize, Deserialize, Default)]
13pub struct AdapterCatalog {
14 pub adapters: HashMap<String, HashSet<String>>,
16}
17
18impl AdapterCatalog {
19 pub fn load_from_file(path: impl AsRef<Path>) -> anyhow::Result<Self> {
21 let path_ref = path.as_ref();
22 let registry_root = env::current_dir().context("unable to resolve registry root")?;
23 let safe_path = normalize_under_root(®istry_root, path_ref)?;
24 let txt = fs::read_to_string(&safe_path).with_context(|| {
25 format!("unable to read adapter registry at {}", safe_path.display())
26 })?;
27 if let Ok(value) = serde_json::from_str::<Self>(&txt) {
28 return Ok(value);
29 }
30
31 #[cfg(feature = "toml")]
32 {
33 if let Ok(value) = toml::from_str::<Self>(&txt) {
34 return Ok(value);
35 }
36 }
37
38 #[cfg(feature = "toml")]
39 {
40 anyhow::bail!(
41 "unsupported registry format in {}: expected JSON or TOML",
42 path_ref.display()
43 );
44 }
45
46 #[cfg(not(feature = "toml"))]
47 {
48 anyhow::bail!(
49 "unsupported registry format in {}: expected JSON (enable `toml` feature for TOML support)",
50 path_ref.display()
51 );
52 }
53 }
54
55 pub fn contains(&self, namespace: &str, adapter: &str, operation: &str) -> bool {
57 let key = format!("{namespace}.{adapter}");
58 self.adapters
59 .get(&key)
60 .map(|ops| ops.contains(operation))
61 .unwrap_or(false)
62 }
63}