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}