pdk-data-storage-lib 1.9.1

PDK Data Storage Library
Documentation
// Copyright (c) 2026, Salesforce, Inc.,
// All rights reserved.
// For full license text, see the LICENSE.txt file

use crate::DataStorageError;
use serde::{Deserialize, Serialize};
use std::marker::PhantomData;

/// This enum is used to wrap the errors returned by the format implementations. In case no format
/// is configured, the default Serialization(fixint) error will be returned or
/// the new Format(Box<dyn Error>) will be used.
#[derive(Debug)]
pub(crate) enum FormatWrapper<F: Format> {
    Default(DefaultFormat, PhantomData<F>),
    #[cfg(feature = "experimental_datastorage_formats")]
    Custom(F),
}

impl<F: Format + Clone> Clone for FormatWrapper<F> {
    fn clone(&self) -> Self {
        match self {
            FormatWrapper::Default(format, _) => {
                FormatWrapper::Default(format.clone(), PhantomData)
            }
            #[cfg(feature = "experimental_datastorage_formats")]
            FormatWrapper::Custom(format) => FormatWrapper::Custom(format.clone()),
        }
    }
}

impl<F: Format> FormatWrapper<F> {
    pub fn serialize<T: Serialize>(&self, item: &T) -> Result<Vec<u8>, DataStorageError> {
        match self {
            FormatWrapper::Default(format, _) => Ok(format.serialize(item)?),
            #[cfg(feature = "experimental_datastorage_formats")]
            FormatWrapper::Custom(format) => format
                .serialize(item)
                .map_err(|e| DataStorageError::Format(e.into())),
        }
    }

    pub fn deserialize<'a, T>(&self, bytes: &'a [u8]) -> Result<T, DataStorageError>
    where
        T: Deserialize<'a>,
    {
        match self {
            FormatWrapper::Default(format, _) => Ok(format.deserialize(bytes)?),
            #[cfg(feature = "experimental_datastorage_formats")]
            FormatWrapper::Custom(format) => format
                .deserialize(bytes)
                .map_err(|e| DataStorageError::Format(e.into())),
        }
    }
}

pub trait Format {
    type SerializeError: Into<Box<dyn std::error::Error>>;
    type DeserializeError: Into<Box<dyn std::error::Error>>;

    fn serialize<T: Serialize>(&self, item: &T) -> Result<Vec<u8>, Self::SerializeError>;

    fn deserialize<'a, T>(&self, bytes: &'a [u8]) -> Result<T, Self::DeserializeError>
    where
        T: Deserialize<'a>;
}

pub(super) type DefaultFormat = Fixint;

/// The default wire format: fixed-width little-endian binary, byte-compatible
/// with the legacy serialization previously used by this library.
#[derive(Debug, Default, Clone)]
pub struct Fixint {
    // Reserved for internal status
    _priv: (),
}

impl Format for Fixint {
    type SerializeError = serde_fixint::Error;
    type DeserializeError = serde_fixint::Error;

    fn serialize<T: serde::Serialize>(&self, item: &T) -> Result<Vec<u8>, Self::SerializeError> {
        serde_fixint::to_vec(item)
    }

    fn deserialize<'a, T>(&self, bytes: &'a [u8]) -> Result<T, Self::SerializeError>
    where
        T: Deserialize<'a>,
    {
        serde_fixint::from_slice(bytes)
    }
}

#[cfg(feature = "experimental_datastorage_formats")]
#[derive(Debug, Default, Clone)]
pub struct MessagePack {
    // Reserved for internal status
    _priv: (),
}

#[cfg(feature = "experimental_datastorage_formats")]
impl Format for MessagePack {
    type SerializeError = rmp_serde::encode::Error;
    type DeserializeError = rmp_serde::decode::Error;

    fn serialize<T: serde::Serialize>(&self, item: &T) -> Result<Vec<u8>, Self::SerializeError> {
        rmp_serde::to_vec(item)
    }

    fn deserialize<'a, T>(&self, bytes: &'a [u8]) -> Result<T, Self::DeserializeError>
    where
        T: Deserialize<'a>,
    {
        rmp_serde::from_slice(bytes)
    }
}