use core::fmt;
use std::collections::HashMap;
use super::store_types::{AllData, DataKind, SerializedItem};
#[derive(Debug)]
pub struct PersistentStoreError {
message: String,
}
impl PersistentStoreError {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
impl std::error::Error for PersistentStoreError {
fn description(&self) -> &str {
&self.message
}
}
impl fmt::Display for PersistentStoreError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.message)
}
}
pub trait PersistentDataStore: Send + Sync {
fn init(
&mut self,
all_data: AllData<SerializedItem, SerializedItem>,
) -> Result<(), PersistentStoreError>;
fn flag(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError>;
fn segment(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError>;
fn all_flags(&self) -> Result<HashMap<String, SerializedItem>, PersistentStoreError>;
fn upsert(
&mut self,
kind: DataKind,
key: &str,
serialized_item: SerializedItem,
) -> Result<bool, PersistentStoreError>;
fn is_initialized(&self) -> bool;
}
#[cfg(test)]
pub(crate) mod tests {
use crate::stores::persistent_store::PersistentDataStore;
use crate::stores::store_types::{AllData, DataKind, SerializedItem};
use std::collections::HashMap;
use super::PersistentStoreError;
pub struct NullPersistentDataStore {
pub(crate) initialized: bool,
}
impl PersistentDataStore for NullPersistentDataStore {
fn init(
&mut self,
_all_data: AllData<SerializedItem, SerializedItem>,
) -> Result<(), PersistentStoreError> {
self.initialized = true;
Ok(())
}
fn flag(&self, _key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
Ok(None)
}
fn segment(&self, _key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
Ok(None)
}
fn all_flags(&self) -> Result<HashMap<String, SerializedItem>, PersistentStoreError> {
Ok(HashMap::new())
}
fn upsert(
&mut self,
_kind: DataKind,
_key: &str,
_serialized_item: SerializedItem,
) -> Result<bool, PersistentStoreError> {
Ok(true)
}
fn is_initialized(&self) -> bool {
self.initialized
}
}
pub struct InMemoryPersistentDataStore {
pub(crate) data: AllData<SerializedItem, SerializedItem>,
pub(crate) initialized: bool,
}
impl PersistentDataStore for InMemoryPersistentDataStore {
fn init(
&mut self,
all_data: AllData<SerializedItem, SerializedItem>,
) -> Result<(), PersistentStoreError> {
self.data = all_data;
self.initialized = true;
Ok(())
}
fn flag(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
Ok(self.data.flags.get(key).map(|value| (*value).clone()))
}
fn segment(&self, key: &str) -> Result<Option<SerializedItem>, PersistentStoreError> {
Ok(self.data.segments.get(key).map(|value| (*value).clone()))
}
fn all_flags(&self) -> Result<HashMap<String, SerializedItem>, PersistentStoreError> {
Ok(self.data.flags.clone())
}
fn upsert(
&mut self,
kind: DataKind,
key: &str,
serialized_item: SerializedItem,
) -> Result<bool, PersistentStoreError> {
let original = match kind {
DataKind::Flag => self.data.flags.insert(key.to_string(), serialized_item),
DataKind::Segment => self.data.segments.insert(key.to_string(), serialized_item),
};
Ok(original.is_some())
}
fn is_initialized(&self) -> bool {
self.initialized
}
}
}