use core::fmt;
use std::borrow::Borrow;
use std::marker::PhantomData;
use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::traits::{data_store, DataStore};
use crate::Error;
pub struct OptionValue<T, DS>
where
DS: DataStore,
{
phantom: PhantomData<T>,
ds: DS,
key: u8,
}
impl<T, E, DS> OptionValue<T, DS>
where
E: fmt::Debug,
T: Serialize + DeserializeOwned,
DS: DataStore<DbError = E>,
{
#[doc(hidden)]
pub fn new(ds: DS, key: u8) -> Self {
Self {
phantom: PhantomData,
ds,
key,
}
}
pub fn set<Q>(&mut self, value: &Q) -> Result<(), Error<E>>
where
T: Borrow<Q>,
Q: Serialize + ?Sized,
{
self.ds.insert::<_, Q, T>(&self.key, value)?;
Ok(())
}
pub fn get(&self) -> Result<Option<T>, Error<E>> {
self.ds.get(&self.key)
}
}
impl<T, E, DS> OptionValue<T, DS>
where
E: fmt::Debug,
T: Serialize + DeserializeOwned,
DS: data_store::Atomic<DbError = E>,
{
pub fn update(&self, op: impl FnMut(T) -> T + Clone) -> Result<(), Error<E>> {
self.ds.atomic_update(&self.key, op)?;
Ok(())
}
pub fn conditional_update<Q>(&self, old: &Q, new: &Q) -> Result<(), Error<E>>
where
T: Borrow<Q>,
Q: Serialize + ?Sized,
{
Ok(self.ds.conditional_update(&self.key, &new, &old)?)
}
}
impl<T, E, DS> fmt::Debug for OptionValue<T, DS>
where
E: fmt::Debug,
T: Serialize + DeserializeOwned + fmt::Debug,
DS: DataStore<DbError = E>,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_fmt(format_args!("{:?}", self.get()))
}
}