claude_agent/config/
memory.rs1use std::collections::HashMap;
7use std::sync::Arc;
8
9use tokio::sync::RwLock;
10
11use super::ConfigResult;
12use super::provider::ConfigProvider;
13
14#[derive(Debug, Default)]
16pub struct MemoryConfigProvider {
17 data: Arc<RwLock<HashMap<String, String>>>,
18 name: String,
19}
20
21impl MemoryConfigProvider {
22 pub fn new() -> Self {
24 Self {
25 data: Arc::new(RwLock::new(HashMap::new())),
26 name: "memory".to_string(),
27 }
28 }
29
30 pub fn named(name: impl Into<String>) -> Self {
32 Self {
33 data: Arc::new(RwLock::new(HashMap::new())),
34 name: name.into(),
35 }
36 }
37
38 pub fn from_data(data: HashMap<String, String>) -> Self {
40 Self {
41 data: Arc::new(RwLock::new(data)),
42 name: "memory".to_string(),
43 }
44 }
45
46 pub fn value(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
48 Arc::get_mut(&mut self.data)
52 .expect(
53 "MemoryConfigProvider::value() called after Arc was shared; use insert() instead",
54 )
55 .get_mut()
56 .insert(key.into(), value.into());
57 self
58 }
59
60 pub async fn insert(&self, key: impl Into<String>, value: impl Into<String>) {
62 let mut data = self.data.write().await;
63 data.insert(key.into(), value.into());
64 }
65
66 pub async fn len(&self) -> usize {
68 self.data.read().await.len()
69 }
70
71 pub async fn is_empty(&self) -> bool {
73 self.data.read().await.is_empty()
74 }
75
76 pub async fn clear(&self) {
78 self.data.write().await.clear();
79 }
80}
81
82#[async_trait::async_trait]
83impl ConfigProvider for MemoryConfigProvider {
84 fn name(&self) -> &str {
85 &self.name
86 }
87
88 async fn get_raw(&self, key: &str) -> ConfigResult<Option<String>> {
89 let data = self.data.read().await;
90 Ok(data.get(key).cloned())
91 }
92
93 async fn set_raw(&self, key: &str, value: &str) -> ConfigResult<()> {
94 let mut data = self.data.write().await;
95 data.insert(key.to_string(), value.to_string());
96 Ok(())
97 }
98
99 async fn delete(&self, key: &str) -> ConfigResult<bool> {
100 let mut data = self.data.write().await;
101 Ok(data.remove(key).is_some())
102 }
103
104 async fn list_keys(&self, prefix: &str) -> ConfigResult<Vec<String>> {
105 let data = self.data.read().await;
106 let keys: Vec<String> = data
107 .keys()
108 .filter(|k| k.starts_with(prefix))
109 .cloned()
110 .collect();
111 Ok(keys)
112 }
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[tokio::test]
120 async fn test_memory_provider_basic() {
121 let provider = MemoryConfigProvider::new();
122
123 provider.set_raw("key1", "value1").await.unwrap();
125 let value = provider.get_raw("key1").await.unwrap();
126 assert_eq!(value, Some("value1".to_string()));
127
128 let value = provider.get_raw("nonexistent").await.unwrap();
130 assert_eq!(value, None);
131 }
132
133 #[tokio::test]
134 async fn test_memory_provider_delete() {
135 let provider = MemoryConfigProvider::new();
136
137 provider.set_raw("key1", "value1").await.unwrap();
138 assert!(provider.delete("key1").await.unwrap());
139 assert!(!provider.delete("key1").await.unwrap());
140
141 let value = provider.get_raw("key1").await.unwrap();
142 assert_eq!(value, None);
143 }
144
145 #[tokio::test]
146 async fn test_memory_provider_list_keys() {
147 let provider = MemoryConfigProvider::new();
148
149 provider.set_raw("app.name", "test").await.unwrap();
150 provider.set_raw("app.version", "1.0").await.unwrap();
151 provider.set_raw("other.key", "value").await.unwrap();
152
153 let keys = provider.list_keys("app.").await.unwrap();
154 assert_eq!(keys.len(), 2);
155 assert!(keys.contains(&"app.name".to_string()));
156 assert!(keys.contains(&"app.version".to_string()));
157 }
158
159 #[tokio::test]
160 async fn test_memory_provider_typed() {
161 use crate::config::provider::ConfigProviderExt;
162
163 let provider = MemoryConfigProvider::new();
164
165 ConfigProviderExt::set(&provider, "count", &42i32)
167 .await
168 .unwrap();
169
170 let count: Option<i32> = ConfigProviderExt::get(&provider, "count").await.unwrap();
172 assert_eq!(count, Some(42));
173 }
174
175 #[tokio::test]
176 async fn test_memory_provider_with_data() {
177 let mut data = HashMap::new();
178 data.insert("key1".to_string(), "value1".to_string());
179 data.insert("key2".to_string(), "value2".to_string());
180
181 let provider = MemoryConfigProvider::from_data(data);
182
183 assert_eq!(provider.len().await, 2);
184 assert_eq!(
185 provider.get_raw("key1").await.unwrap(),
186 Some("value1".to_string())
187 );
188 }
189}