composable_runtime/config/
types.rs1use anyhow::Result;
2use std::collections::HashMap;
3use std::path::Path;
4
5pub type PropertyMap = HashMap<String, serde_json::Value>;
7
8#[derive(Debug, Clone)]
10pub struct GenericDefinition {
11 pub category: String,
12 pub name: String,
13 pub properties: PropertyMap,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum Operator {
21 Equals(String),
22 NotEquals(String),
23 In(Vec<String>),
24 NotIn(Vec<String>),
25 Exists,
26 DoesNotExist,
27}
28
29#[derive(Debug, Clone)]
31pub struct Condition {
32 pub key: String,
33 pub operator: Operator,
34}
35
36#[derive(Debug, Clone)]
39pub struct Selector {
40 pub conditions: Vec<Condition>,
41}
42
43impl Selector {
44 pub fn matches(&self, properties: &HashMap<String, Option<String>>) -> bool {
45 self.conditions.iter().all(|c| c.matches(properties))
46 }
47}
48
49impl Condition {
50 fn matches(&self, properties: &HashMap<String, Option<String>>) -> bool {
51 match &self.operator {
52 Operator::Equals(expected) => properties
53 .get(&self.key)
54 .is_some_and(|v| v.as_ref().is_some_and(|v| v == expected)),
55 Operator::NotEquals(expected) => properties
56 .get(&self.key)
57 .is_some_and(|v| v.as_ref().is_some_and(|v| v != expected)),
58 Operator::In(values) => properties
59 .get(&self.key)
60 .is_some_and(|v| v.as_ref().is_some_and(|v| values.iter().any(|e| v == e))),
61 Operator::NotIn(values) => properties
62 .get(&self.key)
63 .is_some_and(|v| v.as_ref().is_some_and(|v| values.iter().all(|e| v != e))),
64 Operator::Exists => properties.contains_key(&self.key),
65 Operator::DoesNotExist => !properties.contains_key(&self.key),
66 }
67 }
68}
69
70#[derive(Debug, Clone)]
72pub struct CategoryClaim {
73 pub category: &'static str,
74 pub selector: Option<Selector>,
75}
76
77impl CategoryClaim {
78 pub fn all(category: &'static str) -> Self {
80 Self {
81 category,
82 selector: None,
83 }
84 }
85
86 pub fn with_selector(category: &'static str, selector: Selector) -> Self {
88 Self {
89 category,
90 selector: Some(selector),
91 }
92 }
93}
94
95pub trait DefinitionLoader {
97 fn claim(&mut self, _path: &Path) -> bool {
100 false
101 }
102
103 fn load(&self) -> Result<Vec<GenericDefinition>>;
105}
106
107pub trait ConfigHandler {
109 fn claimed_categories(&self) -> Vec<CategoryClaim>;
113
114 fn claimed_properties(&self) -> HashMap<&str, &[&str]> {
119 HashMap::new()
120 }
121
122 fn handle_category(
125 &mut self,
126 category: &str,
127 name: &str,
128 properties: PropertyMap,
129 ) -> Result<()>;
130
131 fn handle_properties(
133 &mut self,
134 _category: &str,
135 _name: &str,
136 _properties: PropertyMap,
137 ) -> Result<()> {
138 Ok(())
139 }
140}