Skip to main content

bare_config/
content.rs

1//! Configuration content trait and implementations.
2//!
3//! This module provides the [`ConfigContent`] trait that defines
4//! a unified interface for CRUD operations on configuration data.
5
6use core::fmt::Display;
7use core::str::FromStr;
8
9use crate::error::{ConfigError, ConfigResult};
10use crate::key::Key;
11use crate::value::Value;
12
13/// Unified trait for configuration content operations.
14pub trait ConfigContent: Sized + Send + Sync + FromStr<Err = ConfigError> + Display {
15    /// Select a value by key path.
16    ///
17    /// # Errors
18    ///
19    /// Returns [`ConfigError::KeyNotFound`] if the key does not exist.
20    /// Returns [`ConfigError::InvalidKey`] if the key format is invalid.
21    fn select(&self, key: &Key) -> ConfigResult<Value>;
22
23    /// Insert a new value at the specified key path.
24    ///
25    /// # Errors
26    ///
27    /// Returns [`ConfigError::KeyAlreadyExists`] if the key already exists.
28    /// Returns [`ConfigError::InvalidKey`] if the key format is invalid.
29    fn insert(&mut self, key: &Key, value: &Value) -> ConfigResult<()>;
30
31    /// Update an existing value at the specified key path.
32    ///
33    /// # Errors
34    ///
35    /// Returns [`ConfigError::KeyDoesNotExist`] if the key does not exist.
36    /// Returns [`ConfigError::InvalidKey`] if the key format is invalid.
37    fn update(&mut self, key: &Key, value: &Value) -> ConfigResult<()>;
38
39    /// Delete a value at the specified key path.
40    ///
41    /// # Errors
42    ///
43    /// Returns [`ConfigError::KeyNotFound`] if the key does not exist.
44    /// Returns [`ConfigError::DeleteError`] if trying to delete the root.
45    fn delete(&mut self, key: &Key) -> ConfigResult<()>;
46
47    /// Upsert (insert or update) a value at the specified key path.
48    ///
49    /// # Errors
50    ///
51    /// Returns [`ConfigError::InvalidKey`] if the key format is invalid.
52    fn upsert(&mut self, key: &Key, value: &Value) -> ConfigResult<()>;
53
54    /// Check if a key exists.
55    fn contains_key(&self, key: &Key) -> bool {
56        self.select(key).is_ok()
57    }
58
59    /// Get all keys at the root level.
60    fn keys(&self) -> Vec<Key> {
61        vec![]
62    }
63
64    /// Get the number of elements at the root level.
65    fn len(&self) -> usize {
66        self.keys().len()
67    }
68
69    /// Check if the configuration is empty.
70    fn is_empty(&self) -> bool {
71        self.len() == 0
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use super::*;
78
79    #[derive(Debug, Clone)]
80    struct Dummy;
81
82    impl Display for Dummy {
83        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
84            write!(f, "dummy")
85        }
86    }
87
88    impl FromStr for Dummy {
89        type Err = ConfigError;
90
91        fn from_str(_s: &str) -> Result<Self, Self::Err> {
92            Ok(Self)
93        }
94    }
95
96    impl ConfigContent for Dummy {
97        fn select(&self, _key: &Key) -> ConfigResult<Value> {
98            Err(ConfigError::Other("not implemented".to_string()))
99        }
100
101        fn insert(&mut self, _key: &Key, _value: &Value) -> ConfigResult<()> {
102            Ok(())
103        }
104
105        fn update(&mut self, _key: &Key, _value: &Value) -> ConfigResult<()> {
106            Ok(())
107        }
108
109        fn delete(&mut self, _key: &Key) -> ConfigResult<()> {
110            Ok(())
111        }
112
113        fn upsert(&mut self, _key: &Key, _value: &Value) -> ConfigResult<()> {
114            Ok(())
115        }
116    }
117
118    #[test]
119    fn test_config_content_trait_methods_exist() {
120        fn check_trait<C: ConfigContent>() {}
121        let _ = check_trait::<Dummy>;
122    }
123}