use serde::{Deserialize, Serialize};
use crate::error::{Result, SynaError};
pub const CURRENT_FORMAT_VERSION: u32 = 1;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PersistedRegistry {
pub version: u32,
pub data: Vec<u8>,
pub _reserved: Vec<u8>,
}
pub fn serialize<T: Serialize>(value: &T) -> Result<Vec<u8>> {
bincode::serialize(value).map_err(SynaError::Serialization)
}
pub fn deserialize<'a, T: Deserialize<'a>>(bytes: &'a [u8]) -> Result<T> {
bincode::deserialize(bytes).map_err(SynaError::Serialization)
}
pub fn wrap_versioned(data: Vec<u8>) -> PersistedRegistry {
PersistedRegistry {
version: CURRENT_FORMAT_VERSION,
data,
_reserved: Vec::new(),
}
}
pub fn unwrap_versioned(persisted: &PersistedRegistry) -> Result<&[u8]> {
if persisted.version > CURRENT_FORMAT_VERSION {
return Err(SynaError::InvalidInput(format!(
"Unsupported feature store format version: {} (max supported: {})",
persisted.version, CURRENT_FORMAT_VERSION
)));
}
Ok(&persisted.data)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_roundtrip() {
let value: Vec<i64> = vec![1, 2, 3, 4, 5];
let bytes = serialize(&value).unwrap();
let restored: Vec<i64> = deserialize(&bytes).unwrap();
assert_eq!(value, restored);
}
#[test]
fn test_versioned_wrap_unwrap() {
let data = vec![1u8, 2, 3, 4];
let wrapped = wrap_versioned(data.clone());
assert_eq!(wrapped.version, CURRENT_FORMAT_VERSION);
let unwrapped = unwrap_versioned(&wrapped).unwrap();
assert_eq!(unwrapped, &data[..]);
}
#[test]
fn test_versioned_future_version_rejected() {
let persisted = PersistedRegistry {
version: 999,
data: vec![],
_reserved: vec![],
};
assert!(unwrap_versioned(&persisted).is_err());
}
}