use std::sync::Arc;
use serde::{Deserialize, Serialize};
use thiserror::Error;
use super::Key;
use crate::{
registry::StateRegistryError,
repository::{Repository, RepositoryError},
};
#[doc(hidden)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SettingItem(pub(crate) serde_json::Value);
crate::register_repository_item!(String => SettingItem, "Setting");
#[derive(Clone)]
pub struct Setting<T> {
repository: Arc<dyn Repository<SettingItem>>,
key: Key<T>,
}
impl<T> Setting<T> {
pub fn new(repository: Arc<dyn Repository<SettingItem>>, key: Key<T>) -> Self {
Self { repository, key }
}
pub async fn get(&self) -> Result<Option<T>, SettingsError>
where
T: for<'de> Deserialize<'de>,
{
match self.repository.get(self.key.name.to_string()).await? {
Some(item) => Ok(Some(serde_json::from_value::<T>(item.0)?)),
None => Ok(None),
}
}
pub async fn update(&self, value: T) -> Result<(), SettingsError>
where
T: Serialize,
{
let json_value = serde_json::to_value(&value)?;
let item = SettingItem(json_value);
self.repository.set(self.key.name.to_string(), item).await?;
Ok(())
}
pub async fn delete(&self) -> Result<(), SettingsError> {
self.repository.remove(self.key.name.to_string()).await?;
Ok(())
}
}
#[derive(Debug, Error)]
pub enum SettingsError {
#[error("Failed to serialize/deserialize setting: {0}")]
Json(#[from] serde_json::Error),
#[error(transparent)]
Repository(#[from] RepositoryError),
#[error(transparent)]
Registry(#[from] StateRegistryError),
}