use crate::{from_value, to_value};
use serde::{de::DeserializeOwned, Serialize};
use std::sync::Arc;
use structfs_core_store::{Codec, DetachedFuture, DetachedReader, DetachedWriter, Path, Record};
pub trait DetachedTypedReader: DetachedReader {
fn read_as_detached<T: DeserializeOwned + Send + 'static>(
&mut self,
from: &Path,
codec: Arc<dyn Codec>,
) -> DetachedFuture<Option<T>> {
let operation = self.read_detached(from);
Box::pin(async move {
operation
.await?
.map(|record| from_value(record.into_value(codec.as_ref())?))
.transpose()
})
}
fn read_typed_detached<T: DeserializeOwned + Send + 'static>(
&mut self,
from: &Path,
) -> DetachedFuture<Option<T>> {
self.read_as_detached(from, Arc::new(structfs_core_store::NoCodec))
}
fn read_json_detached(
&mut self,
from: &Path,
codec: Arc<dyn Codec>,
) -> DetachedFuture<Option<serde_json::Value>> {
let operation = self.read_as_detached::<structfs_core_store::Value>(from, codec);
Box::pin(async move { operation.await?.map(crate::value_to_json).transpose() })
}
}
impl<R: DetachedReader + ?Sized> DetachedTypedReader for R {}
pub trait DetachedTypedWriter: DetachedWriter {
fn write_as_detached<T: Serialize + ?Sized>(
&mut self,
to: &Path,
data: &T,
) -> DetachedFuture<Path> {
match to_value(data) {
Ok(value) => self.write_detached(to, Record::parsed(value)),
Err(error) => Box::pin(async move { Err(error) }),
}
}
fn write_typed_detached<T: Serialize + ?Sized>(
&mut self,
to: &Path,
data: &T,
) -> DetachedFuture<Path> {
self.write_as_detached(to, data)
}
fn write_json_detached(&mut self, to: &Path, data: serde_json::Value) -> DetachedFuture<Path> {
self.write_as_detached(to, &data)
}
}
impl<W: DetachedWriter + ?Sized> DetachedTypedWriter for W {}