Skip to main content

numcodecs_onion/
lib.rs

1//! [![CI Status]][workflow] [![MSRV]][repo] [![Latest Version]][crates.io] [![Rust Doc Crate]][docs.rs] [![Rust Doc Main]][docs]
2//!
3//! [CI Status]: https://img.shields.io/github/actions/workflow/status/juntyr/numcodecs-rs/ci.yml?branch=main
4//! [workflow]: https://github.com/juntyr/numcodecs-rs/actions/workflows/ci.yml?query=branch%3Amain
5//!
6//! [MSRV]: https://img.shields.io/badge/MSRV-1.87.0-blue
7//! [repo]: https://github.com/juntyr/numcodecs-rs
8//!
9//! [Latest Version]: https://img.shields.io/crates/v/numcodecs-onion
10//! [crates.io]: https://crates.io/crates/numcodecs-onion
11//!
12//! [Rust Doc Crate]: https://img.shields.io/docsrs/numcodecs-onion
13//! [docs.rs]: https://docs.rs/numcodecs-onion/
14//!
15//! [Rust Doc Main]: https://img.shields.io/badge/docs-main-blue
16//! [docs]: https://juntyr.github.io/numcodecs-rs/numcodecs_onion
17//!
18//! Onion identity meta-codec implementation for the [`numcodecs`] API.
19
20use numcodecs::{
21    AnyArray, AnyArrayView, AnyArrayViewMut, AnyCowArray, Codec, DynCodec, ErasedDynCodec,
22    ErasedError, StaticCodec, StaticCodecConfig, StaticCodecVersion,
23};
24use numcodecs_registry::GlobalRegistry;
25use schemars::JsonSchema;
26use serde::{Deserialize, Serialize};
27use thiserror::Error;
28
29#[derive(Clone, Serialize, Deserialize, JsonSchema)]
30#[serde(deny_unknown_fields)]
31/// Onion identity meta-codec which wraps an existing codec and passes the
32/// inputs and outputs unchanged to and from this codec during encoding and
33/// decoding.
34pub struct OnionCodec {
35    /// The configuration of the wrapped codec.
36    #[serde(serialize_with = "DynCodec::get_config")]
37    #[serde(deserialize_with = "GlobalRegistry::codec_from_config")]
38    #[schemars(schema_with = "ErasedDynCodec::codec_config_schema")]
39    pub codec: ErasedDynCodec,
40    /// The codec's encoding format version. Do not provide this parameter explicitly.
41    #[serde(default, rename = "_version")]
42    pub version: StaticCodecVersion<1, 0, 0>,
43}
44
45impl Codec for OnionCodec {
46    type Error = OnionCodecError;
47
48    fn encode(&self, data: AnyCowArray) -> Result<AnyArray, Self::Error> {
49        self.codec
50            .encode(data)
51            .map_err(|err| OnionCodecError { error: err })
52    }
53
54    fn decode(&self, encoded: AnyCowArray) -> Result<AnyArray, Self::Error> {
55        self.codec
56            .decode(encoded)
57            .map_err(|err| OnionCodecError { error: err })
58    }
59
60    fn decode_into(
61        &self,
62        encoded: AnyArrayView,
63        decoded: AnyArrayViewMut,
64    ) -> Result<(), Self::Error> {
65        self.codec
66            .decode_into(encoded, decoded)
67            .map_err(|err| OnionCodecError { error: err })
68    }
69}
70
71impl StaticCodec for OnionCodec {
72    const CODEC_ID: &'static str = "onion.rs";
73
74    type Config<'de> = Self;
75
76    fn from_config(config: Self::Config<'_>) -> Self {
77        config
78    }
79
80    fn get_config(&self) -> StaticCodecConfig<'_, Self> {
81        StaticCodecConfig::from(self)
82    }
83}
84
85#[derive(Debug, Error)]
86/// Error that may occur when applying the [`OnionCodec`].
87#[error(transparent)]
88pub struct OnionCodecError {
89    error: ErasedError,
90}
91
92// FIXME: provide global registry elsewhere
93numcodecs_registry::export_global! {
94    static REGISTRY: numcodecs_registry::EmptyRegistry = numcodecs_registry::EmptyRegistry;
95}