Skip to main content

origin_settings/
store.rs

1use crate::SETTINGS_NAMESPACE;
2use async_trait::async_trait;
3use origin_domain::{Clock, Result};
4use origin_storage::{Record, Storage, StorageKey};
5use std::fmt::Debug;
6use std::sync::Arc;
7
8/// Raw persistence for settings. Values are JSON text.
9///
10/// Most code should use [`crate::Settings`] instead — this is the port an adapter
11/// implements.
12#[async_trait]
13pub trait SettingsStore: Debug + Send + Sync + 'static {
14    async fn get_raw(&self, key: &str) -> Result<Option<String>>;
15    async fn set_raw(&self, key: &str, value: String) -> Result<()>;
16    async fn remove(&self, key: &str) -> Result<()>;
17    async fn keys(&self) -> Result<Vec<String>>;
18}
19
20/// Settings on top of any [`Storage`] backend.
21///
22/// Settings are user data, not cache: records are written without an expiry, so a
23/// cache sweep can never drop them.
24#[derive(Debug, Clone)]
25pub struct StorageSettingsStore {
26    storage: Arc<dyn Storage>,
27    clock: Arc<dyn Clock>,
28}
29
30impl StorageSettingsStore {
31    pub fn new(storage: Arc<dyn Storage>, clock: Arc<dyn Clock>) -> Self {
32        Self { storage, clock }
33    }
34
35    fn key(name: &str) -> StorageKey {
36        StorageKey::new(SETTINGS_NAMESPACE, name)
37    }
38}
39
40#[async_trait]
41impl SettingsStore for StorageSettingsStore {
42    async fn get_raw(&self, key: &str) -> Result<Option<String>> {
43        Ok(self
44            .storage
45            .get(&Self::key(key))
46            .await?
47            .map(|record| record.value))
48    }
49
50    async fn set_raw(&self, key: &str, value: String) -> Result<()> {
51        self.storage
52            .put(&Self::key(key), Record::new(value, self.clock.now()))
53            .await
54    }
55
56    async fn remove(&self, key: &str) -> Result<()> {
57        self.storage.delete(&Self::key(key)).await
58    }
59
60    async fn keys(&self) -> Result<Vec<String>> {
61        Ok(self
62            .storage
63            .keys(SETTINGS_NAMESPACE)
64            .await?
65            .into_iter()
66            .map(|key| key.key().to_owned())
67            .collect())
68    }
69}