gglib_core/services/
settings_service.rs1use crate::ports::{CoreError, SettingsRepository};
4use crate::settings::{Settings, SettingsUpdate, validate_settings};
5use std::sync::Arc;
6
7pub struct SettingsService {
9 repo: Arc<dyn SettingsRepository>,
10}
11
12impl SettingsService {
13 pub fn new(repo: Arc<dyn SettingsRepository>) -> Self {
15 Self { repo }
16 }
17
18 pub async fn get(&self) -> Result<Settings, CoreError> {
20 self.repo.load().await.map_err(CoreError::from)
21 }
22
23 pub async fn update(&self, update: SettingsUpdate) -> Result<Settings, CoreError> {
25 let mut current = self.repo.load().await.map_err(CoreError::from)?;
26 current.merge(&update);
27 validate_settings(¤t)?;
28 self.repo.save(¤t).await.map_err(CoreError::from)?;
29 Ok(current)
30 }
31
32 pub async fn save(&self, settings: &Settings) -> Result<(), CoreError> {
34 validate_settings(settings)?;
35 self.repo.save(settings).await.map_err(CoreError::from)
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::ports::RepositoryError;
43 use async_trait::async_trait;
44 use std::sync::Mutex;
45
46 struct MockSettingsRepo {
47 settings: Mutex<Settings>,
48 }
49
50 impl MockSettingsRepo {
51 fn new() -> Self {
52 Self {
53 settings: Mutex::new(Settings::with_defaults()),
54 }
55 }
56 }
57
58 #[async_trait]
59 impl SettingsRepository for MockSettingsRepo {
60 async fn load(&self) -> Result<Settings, RepositoryError> {
61 Ok(self.settings.lock().unwrap().clone())
62 }
63
64 async fn save(&self, settings: &Settings) -> Result<(), RepositoryError> {
65 *self.settings.lock().unwrap() = settings.clone();
66 Ok(())
67 }
68 }
69
70 #[tokio::test]
71 async fn test_get_default_settings() {
72 let repo = Arc::new(MockSettingsRepo::new());
73 let service = SettingsService::new(repo);
74
75 let settings = service.get().await.unwrap();
76 assert_eq!(settings.default_context_size, Some(4096));
77 }
78
79 #[tokio::test]
80 async fn test_update_settings() {
81 let repo = Arc::new(MockSettingsRepo::new());
82 let service = SettingsService::new(repo);
83
84 let update = SettingsUpdate {
85 default_context_size: Some(Some(8192)),
86 ..Default::default()
87 };
88
89 let updated = service.update(update).await.unwrap();
90 assert_eq!(updated.default_context_size, Some(8192));
91
92 let fetched = service.get().await.unwrap();
94 assert_eq!(fetched.default_context_size, Some(8192));
95 }
96}