claude_agent/config/
provider.rs1use serde::{Serialize, de::DeserializeOwned};
4
5use super::ConfigResult;
6
7#[async_trait::async_trait]
9pub trait ConfigProvider: Send + Sync {
10 fn name(&self) -> &str;
12
13 async fn get_raw(&self, key: &str) -> ConfigResult<Option<String>>;
15
16 async fn set_raw(&self, key: &str, value: &str) -> ConfigResult<()>;
18
19 async fn delete(&self, key: &str) -> ConfigResult<bool>;
21
22 async fn list_keys(&self, prefix: &str) -> ConfigResult<Vec<String>>;
24}
25
26pub trait ConfigProviderExt: ConfigProvider {
28 fn get<T: DeserializeOwned + Send>(
30 &self,
31 key: &str,
32 ) -> impl std::future::Future<Output = ConfigResult<Option<T>>> + Send
33 where
34 Self: Sync,
35 {
36 async move {
37 match self.get_raw(key).await? {
38 Some(raw) => {
39 let value: T = serde_json::from_str(&raw).map_err(|e| {
40 super::ConfigError::InvalidValue {
41 key: key.to_string(),
42 message: e.to_string(),
43 }
44 })?;
45 Ok(Some(value))
46 }
47 None => Ok(None),
48 }
49 }
50 }
51
52 fn set<T: Serialize + Send + Sync>(
54 &self,
55 key: &str,
56 value: &T,
57 ) -> impl std::future::Future<Output = ConfigResult<()>> + Send
58 where
59 Self: Sync,
60 {
61 async move {
62 let raw = serde_json::to_string(value)?;
63 self.set_raw(key, &raw).await
64 }
65 }
66}
67
68impl<P: ConfigProvider + ?Sized> ConfigProviderExt for P {}