use std::pin::Pin;
use crate::record::ActiveRecord;
use super::Result;
use async_trait::async_trait;
use futures_core::Stream;
use indexmap::IndexMap;
use vantage_types::Record;
#[async_trait]
pub trait ValueSet {
type Id: Send + Sync + Clone;
type Value: Send + Sync + Clone;
}
#[async_trait]
pub trait ReadableValueSet: ValueSet {
async fn list_values(&self) -> Result<IndexMap<Self::Id, Record<Self::Value>>>;
async fn get_value(&self, id: &Self::Id) -> Result<Record<Self::Value>>;
async fn get_some_value(&self) -> Result<Option<(Self::Id, Record<Self::Value>)>>;
#[allow(clippy::type_complexity)]
fn stream_values(
&self,
) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + '_>>
where
Self: Sync,
{
Box::pin(async_stream::stream! {
let records = self.list_values().await;
match records {
Ok(map) => {
for item in map {
yield Ok(item);
}
}
Err(e) => yield Err(e),
}
})
}
}
#[async_trait]
pub trait WritableValueSet: ValueSet {
async fn insert_value(
&self,
id: &Self::Id,
record: &Record<Self::Value>,
) -> Result<Record<Self::Value>>;
async fn replace_value(
&self,
id: &Self::Id,
record: &Record<Self::Value>,
) -> Result<Record<Self::Value>>;
async fn patch_value(
&self,
id: &Self::Id,
partial: &Record<Self::Value>,
) -> Result<Record<Self::Value>>;
async fn delete(&self, id: &Self::Id) -> Result<()>;
async fn delete_all(&self) -> Result<()>;
}
#[async_trait]
pub trait InsertableValueSet: ValueSet {
async fn insert_return_id_value(&self, record: &Record<Self::Value>) -> Result<Self::Id>;
}
#[async_trait]
pub trait ActiveRecordSet: ReadableValueSet + WritableValueSet {
async fn get_value_record(&self, id: &Self::Id) -> Result<ActiveRecord<'_, Self>>;
async fn list_value_records(&self) -> Result<Vec<ActiveRecord<'_, Self>>>;
}
#[async_trait]
impl<T> ActiveRecordSet for T
where
T: ReadableValueSet + WritableValueSet + Sync,
{
async fn get_value_record(&self, id: &Self::Id) -> Result<ActiveRecord<'_, Self>> {
let record = self.get_value(id).await?;
Ok(ActiveRecord::new(id.clone(), record, self))
}
async fn list_value_records(&self) -> Result<Vec<ActiveRecord<'_, Self>>> {
let items = self.list_values().await?;
Ok(items
.into_iter()
.map(|(id, record)| ActiveRecord::new(id, record, self))
.collect::<Vec<_>>())
}
}