use super::DataStoreCategoryFrontendAPI;
use crate::Result;
use crate::{Outcome, TypedValue, TypedValueMap, TypedValueVec};
#[derive(Debug, Clone, Display, PartialEq)]
pub enum DataStoreFeature {
Get,
Store,
PopulateUser,
Other(String),
}
pub struct FeatureReturn {
implemented: bool,
outcome: Result<Outcome>,
}
impl FeatureReturn {
pub fn new(result: Result<Outcome>) -> Self {
Self {
implemented: true,
outcome: result,
}
}
pub fn new_unimplemented(msg: String) -> Self {
Self {
implemented: false,
outcome: Err(error!(&msg)),
}
}
pub fn outcome(&self) -> Result<&Outcome> {
match &self.outcome {
Ok(o) => Ok(o),
Err(e) => Err((*e).clone()),
}
}
pub fn implemented(&self) -> bool {
self.implemented
}
}
pub trait DataStoreFrontendAPI {
fn name(&self) -> Result<&str>;
fn category(&self) -> Result<Box<dyn DataStoreCategoryFrontendAPI>>;
fn class(&self, backend: Option<TypedValueMap>) -> Result<String>;
fn call(
&self,
func: &str,
pos_args: Option<TypedValueVec>,
kw_args: Option<TypedValueMap>,
backend: Option<TypedValueMap>,
) -> Result<Outcome>;
fn get(&self, key: &str) -> Result<Option<TypedValue>>;
fn contains(&self, query: &str) -> Result<bool>;
fn remove(&self, key: &str) -> Result<Option<TypedValue>>;
fn store(&self, key: &str, obj: TypedValue) -> Result<bool>;
fn items(&self) -> Result<TypedValueMap>;
fn keys(&self) -> Result<Vec<String>> {
Ok(self
.items()?
.typed_values()
.keys()
.map(|k| k.to_string())
.collect())
}
fn populate_user(&self, _user_id: &str, _ds_name: &str) -> Result<FeatureReturn> {
self.unimplemented(current_func!())
}
fn validate_password(
&self,
_username: &str,
_password: &str,
_user_id: &str,
_ds_name: &str,
) -> Result<FeatureReturn> {
self.unimplemented(current_func!())
}
fn unimplemented(&self, feature: &str) -> Result<FeatureReturn> {
Ok(FeatureReturn::new_unimplemented(
self._feature_not_implemented(feature)?,
))
}
fn _feature_not_implemented(&self, feature: &str) -> Result<String> {
Ok(format!(
"'{}' does not implement feature '{}' (data store category: '{}')",
self.name()?,
feature.to_string(),
self.category()?.name()
))
}
}