aws_runtime/env_config/
property.rs1use std::collections::HashMap;
9use std::fmt;
10
11#[derive(Debug, Clone, Eq, PartialEq)]
13pub struct Property {
14    key: String,
15    value: String,
16}
17
18impl Property {
19    pub fn value(&self) -> &str {
21        &self.value
22    }
23
24    pub fn key(&self) -> &str {
26        &self.key
27    }
28
29    pub fn new(key: String, value: String) -> Self {
31        Property { key, value }
32    }
33}
34
35type SectionKey = String;
36type SectionName = String;
37type PropertyName = String;
38type SubPropertyName = String;
39type PropertyValue = String;
40
41#[derive(Clone, Debug, PartialEq, Eq, Hash)]
51pub struct PropertiesKey {
52    section_key: SectionKey,
53    section_name: SectionName,
54    property_name: PropertyName,
55    sub_property_name: Option<SubPropertyName>,
56}
57
58impl PropertiesKey {
59    pub fn builder() -> PropertiesKeyBuilder {
61        Default::default()
62    }
63}
64
65impl fmt::Display for PropertiesKey {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        let PropertiesKey {
68            section_key,
69            section_name,
70            property_name,
71            sub_property_name,
72        } = self;
73        match sub_property_name {
74            Some(sub_property_name) => {
75                write!(
76                    f,
77                    "[{section_key} {section_name}].{property_name}.{sub_property_name}"
78                )
79            }
80            None => {
81                write!(f, "[{section_key} {section_name}].{property_name}")
82            }
83        }
84    }
85}
86
87#[derive(Debug, Default)]
89pub struct PropertiesKeyBuilder {
90    section_key: Option<SectionKey>,
91    section_name: Option<SectionName>,
92    property_name: Option<PropertyName>,
93    sub_property_name: Option<SubPropertyName>,
94}
95
96impl PropertiesKeyBuilder {
97    pub fn section_key(mut self, section_key: impl Into<String>) -> Self {
99        self.section_key = Some(section_key.into());
100        self
101    }
102
103    pub fn section_name(mut self, section_name: impl Into<String>) -> Self {
105        self.section_name = Some(section_name.into());
106        self
107    }
108
109    pub fn property_name(mut self, property_name: impl Into<String>) -> Self {
111        self.property_name = Some(property_name.into());
112        self
113    }
114
115    pub fn sub_property_name(mut self, sub_property_name: impl Into<String>) -> Self {
117        self.sub_property_name = Some(sub_property_name.into());
118        self
119    }
120
121    pub fn build(self) -> Result<PropertiesKey, String> {
124        Ok(PropertiesKey {
125            section_key: self
126                .section_key
127                .ok_or("A section_key is required".to_owned())?,
128            section_name: self
129                .section_name
130                .ok_or("A section_name is required".to_owned())?,
131            property_name: self
132                .property_name
133                .ok_or("A property_name is required".to_owned())?,
134            sub_property_name: self.sub_property_name,
135        })
136    }
137}
138
139#[derive(Clone, Debug, Default, PartialEq, Eq)]
141pub struct Properties {
142    inner: HashMap<PropertiesKey, PropertyValue>,
143}
144
145#[allow(dead_code)]
146impl Properties {
147    pub fn new() -> Self {
149        Default::default()
150    }
151
152    #[cfg(test)]
153    pub(crate) fn new_from_slice(slice: &[(PropertiesKey, PropertyValue)]) -> Self {
154        let mut properties = Self::new();
155        for (key, value) in slice {
156            properties.insert(key.clone(), value.clone());
157        }
158        properties
159    }
160
161    pub fn insert(&mut self, properties_key: PropertiesKey, value: PropertyValue) {
163        let _ = self
164            .inner
165            .entry(properties_key.clone())
167            .and_modify(|v| {
168                tracing::trace!("overwriting {properties_key}: was {v}, now {value}");
169                v.clone_from(&value);
170            })
171            .or_insert(value);
172    }
173
174    pub fn get(&self, properties_key: &PropertiesKey) -> Option<&PropertyValue> {
176        self.inner.get(properties_key)
177    }
178}