Skip to main content

yugendb_core/
codec.rs

1//! Codec model for serialising and deserialising typed values.
2
3use serde::{de::DeserializeOwned, Serialize};
4
5use crate::{Result, ValueBytes, YugenDbError};
6
7/// Object-safe codec contract used by stores.
8///
9/// The byte-level methods keep the trait usable behind `dyn Codec`. The
10/// [`CodecExt`] extension trait provides ergonomic typed `serialise` and
11/// `deserialise` helpers for all codec implementations.
12pub trait Codec: Send + Sync {
13    /// Stable codec name stored in value metadata.
14    fn name(&self) -> &'static str;
15
16    /// Serialises a JSON value into bytes for storage.
17    fn serialise_json_value(&self, value: &serde_json::Value) -> Result<ValueBytes>;
18
19    /// Deserialises bytes into a JSON value.
20    fn deserialise_json_value(&self, bytes: &ValueBytes) -> Result<serde_json::Value>;
21}
22
23/// Typed codec helpers.
24pub trait CodecExt: Codec {
25    /// Serialises a typed value into bytes.
26    fn serialise<T>(&self, value: &T) -> Result<ValueBytes>
27    where
28        T: Serialize,
29    {
30        let json_value = serde_json::to_value(value)
31            .map_err(|error| YugenDbError::serialisation_error(error.to_string()))?;
32        self.serialise_json_value(&json_value)
33    }
34
35    /// Deserialises bytes into a typed value.
36    fn deserialise<T>(&self, bytes: &ValueBytes) -> Result<T>
37    where
38        T: DeserializeOwned,
39    {
40        let json_value = self.deserialise_json_value(bytes)?;
41        serde_json::from_value(json_value)
42            .map_err(|error| YugenDbError::deserialisation_error(error.to_string()))
43    }
44}
45
46impl<T> CodecExt for T where T: Codec + ?Sized {}
47
48/// JSON codec using `serde_json`.
49#[derive(Debug, Clone, Copy, Default)]
50pub struct JsonCodec;
51
52impl Codec for JsonCodec {
53    fn name(&self) -> &'static str {
54        "json"
55    }
56
57    fn serialise_json_value(&self, value: &serde_json::Value) -> Result<ValueBytes> {
58        let bytes = serde_json::to_vec(value)
59            .map_err(|error| YugenDbError::serialisation_error(error.to_string()))?;
60        Ok(ValueBytes::from(bytes))
61    }
62
63    fn deserialise_json_value(&self, bytes: &ValueBytes) -> Result<serde_json::Value> {
64        serde_json::from_slice(bytes.as_slice())
65            .map_err(|error| YugenDbError::deserialisation_error(error.to_string()))
66    }
67}