-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
138 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
use std::{error::Error, marker::PhantomData}; | ||
|
||
use serde::{Deserializer, Serializer}; | ||
|
||
use crate::{AnyArray, AnyArrayView, AnyArrayViewMut, AnyCowArray}; | ||
|
||
/// Compression codec that [`encode`][`Codec::encode`]s and | ||
/// [`decode`][`Codec::decode`]s numeric n-dimensional arrays. | ||
pub trait Codec: 'static + Send + Sync + Clone { | ||
/// Error type that may be returned during [`encode`][`Codec::encode`]ing | ||
/// and [`decode`][`Codec::decode`]ing. | ||
type Error: 'static + Send + Sync + Error; | ||
|
||
/// Encodes the `data` and returns the result. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Errors if encoding the buffer fails. | ||
fn encode(&self, data: AnyCowArray) -> Result<AnyArray, Self::Error>; | ||
|
||
/// Decodes the `encoded` data and returns the result. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Errors if decoding the buffer fails. | ||
fn decode(&self, encoded: AnyCowArray) -> Result<AnyArray, Self::Error>; | ||
|
||
/// Decodes the `encoded` data and writes the result into the provided | ||
/// `decoded` output. | ||
/// | ||
/// The output must have the correct type and shape. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Errors if decoding the buffer fails. | ||
fn decode_into( | ||
&self, | ||
encoded: AnyArrayView, | ||
decoded: AnyArrayViewMut, | ||
) -> Result<(), Self::Error>; | ||
|
||
/// Serializes the configuration parameters for this codec. | ||
/// | ||
/// The config must include an `id` field with the [`DynCodecType::codec_id`]. | ||
/// The config must be compatible with JSON encoding. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Errors if serializing the codec configuration fails. | ||
fn get_config<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>; | ||
} | ||
|
||
/// Statically typed compression codec. | ||
pub trait StaticCodec: Codec { | ||
/// Codec identifier. | ||
const CODEC_ID: &'static str; | ||
|
||
/// Instantiate a codec from a serialized `config`uration. | ||
/// | ||
/// The config must be compatible with JSON encoding. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Errors if constructing the codec fails. | ||
fn from_config<'de, D: Deserializer<'de>>(config: D) -> Result<Self, D::Error>; | ||
} | ||
|
||
/// Dynamically typed compression codec. | ||
/// | ||
/// Every codec that implements [`StaticCodec`] also implements [`DynCodec`]. | ||
pub trait DynCodec: Codec { | ||
/// Type object type for this codec. | ||
type Type: DynCodecType; | ||
|
||
/// Returns the type object for this codec. | ||
fn ty(&self) -> Self::Type; | ||
} | ||
|
||
/// Type object for dynamically typed compression codecs. | ||
pub trait DynCodecType: 'static + Send + Sync { | ||
/// Type of the instances of this codec type object. | ||
type Codec: DynCodec<Type = Self>; | ||
|
||
/// Codec identifier. | ||
fn codec_id(&self) -> &str; | ||
|
||
/// Instantiate a codec of this type from a serialized `config`uration. | ||
/// | ||
/// The config must be compatible with JSON encoding. | ||
/// | ||
/// # Errors | ||
/// | ||
/// Errors if constructing the codec fails. | ||
fn codec_from_config<'de, D: Deserializer<'de>>( | ||
&self, | ||
config: D, | ||
) -> Result<Self::Codec, D::Error>; | ||
} | ||
|
||
impl<T: StaticCodec> DynCodec for T { | ||
type Type = StaticCodecType<Self>; | ||
|
||
fn ty(&self) -> Self::Type { | ||
StaticCodecType::of() | ||
} | ||
} | ||
|
||
/// Type object for statically typed compression codecs. | ||
pub struct StaticCodecType<T: StaticCodec> { | ||
_marker: PhantomData<T>, | ||
} | ||
|
||
impl<T: StaticCodec> StaticCodecType<T> { | ||
/// Statically obtain the type for a statically typed codec. | ||
#[must_use] | ||
pub const fn of() -> Self { | ||
Self { | ||
_marker: PhantomData::<T>, | ||
} | ||
} | ||
} | ||
|
||
impl<T: StaticCodec> DynCodecType for StaticCodecType<T> { | ||
type Codec = T; | ||
|
||
fn codec_id(&self) -> &str { | ||
T::CODEC_ID | ||
} | ||
|
||
fn codec_from_config<'de, D: Deserializer<'de>>( | ||
&self, | ||
config: D, | ||
) -> Result<Self::Codec, D::Error> { | ||
T::from_config(config) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters