use crate::buf::BufferFormat;
use crate::buf::BufferProvider;
use crate::data_provider::DynamicDryDataProvider;
use crate::prelude::*;
use crate::DryDataProvider;
use serde::de::Deserialize;
use yoke::Yokeable;
#[derive(Debug)]
pub struct DeserializingBufferProvider<'a, P: ?Sized>(&'a P);
pub trait AsDeserializingBufferProvider {
fn as_deserializing(&self) -> DeserializingBufferProvider<'_, Self>;
}
impl<P> AsDeserializingBufferProvider for P
where
P: BufferProvider + ?Sized,
{
fn as_deserializing(&self) -> DeserializingBufferProvider<'_, Self> {
DeserializingBufferProvider(self)
}
}
fn deserialize_impl<'data, M>(
#[allow(unused_variables)] bytes: &'data [u8],
buffer_format: BufferFormat,
) -> Result<<M::DataStruct as Yokeable<'data>>::Output, DataError>
where
M: DynamicDataMarker,
for<'de> <M::DataStruct as Yokeable<'de>>::Output: Deserialize<'de>,
{
match buffer_format {
#[cfg(feature = "deserialize_json")]
BufferFormat::Json => {
let mut d = serde_json::Deserializer::from_slice(bytes);
Ok(Deserialize::deserialize(&mut d)?)
}
#[cfg(feature = "deserialize_bincode_1")]
BufferFormat::Bincode1 => {
use bincode::Options;
let options = bincode::DefaultOptions::new()
.with_fixint_encoding()
.allow_trailing_bytes();
let mut d = bincode::de::Deserializer::from_slice(bytes, options);
Ok(Deserialize::deserialize(&mut d)?)
}
#[cfg(feature = "deserialize_postcard_1")]
BufferFormat::Postcard1 => {
let mut d = postcard::Deserializer::from_bytes(bytes);
Ok(Deserialize::deserialize(&mut d)?)
}
#[allow(unreachable_patterns)]
_ => {
buffer_format.check_available()?;
unreachable!()
}
}
}
impl DataPayload<BufferMarker> {
pub fn into_deserialized<M>(
self,
buffer_format: BufferFormat,
) -> Result<DataPayload<M>, DataError>
where
M: DynamicDataMarker,
for<'de> <M::DataStruct as Yokeable<'de>>::Output: Deserialize<'de>,
{
self.try_map_project(|bytes, _| deserialize_impl::<M>(bytes, buffer_format))
}
}
impl<P, M> DynamicDataProvider<M> for DeserializingBufferProvider<'_, P>
where
M: DynamicDataMarker,
P: BufferProvider + ?Sized,
for<'de> <M::DataStruct as Yokeable<'de>>::Output: Deserialize<'de>,
{
fn load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponse<M>, DataError> {
let buffer_response = self.0.load_data(marker, req)?;
let buffer_format = buffer_response.metadata.buffer_format.ok_or_else(|| {
DataErrorKind::Deserialize
.with_str_context("BufferProvider didn't set BufferFormat")
.with_req(marker, req)
})?;
Ok(DataResponse {
metadata: buffer_response.metadata,
payload: buffer_response
.payload
.into_deserialized(buffer_format)
.map_err(|e| e.with_req(marker, req))?,
})
}
}
impl<P, M> DynamicDryDataProvider<M> for DeserializingBufferProvider<'_, P>
where
M: DynamicDataMarker,
P: DynamicDryDataProvider<BufferMarker> + ?Sized,
for<'de> <M::DataStruct as Yokeable<'de>>::Output: Deserialize<'de>,
{
fn dry_load_data(
&self,
marker: DataMarkerInfo,
req: DataRequest,
) -> Result<DataResponseMetadata, DataError> {
self.0.dry_load_data(marker, req)
}
}
impl<P, M> DataProvider<M> for DeserializingBufferProvider<'_, P>
where
M: DataMarker,
P: DynamicDataProvider<BufferMarker> + ?Sized,
for<'de> <M::DataStruct as Yokeable<'de>>::Output: Deserialize<'de>,
{
fn load(&self, req: DataRequest) -> Result<DataResponse<M>, DataError> {
self.load_data(M::INFO, req)
}
}
impl<P, M> DryDataProvider<M> for DeserializingBufferProvider<'_, P>
where
M: DataMarker,
P: DynamicDryDataProvider<BufferMarker> + ?Sized,
for<'de> <M::DataStruct as Yokeable<'de>>::Output: Deserialize<'de>,
{
fn dry_load(&self, req: DataRequest) -> Result<DataResponseMetadata, DataError> {
self.0.dry_load_data(M::INFO, req)
}
}
#[cfg(feature = "deserialize_json")]
impl From<serde_json::error::Error> for DataError {
fn from(e: serde_json::error::Error) -> Self {
DataErrorKind::Deserialize
.with_str_context("serde_json")
.with_display_context(&e)
}
}
#[cfg(feature = "deserialize_bincode_1")]
impl From<bincode::Error> for DataError {
fn from(e: bincode::Error) -> Self {
DataErrorKind::Deserialize
.with_str_context("bincode")
.with_display_context(&e)
}
}
#[cfg(feature = "deserialize_postcard_1")]
impl From<postcard::Error> for DataError {
fn from(e: postcard::Error) -> Self {
DataErrorKind::Deserialize
.with_str_context("postcard")
.with_display_context(&e)
}
}