//! Storage-layer serialization helpers that map core serde errors to StorageError.
//!
//! This module provides a single source of truth for serialization in the storage layer,
//! eliminating duplication of the error mapping pattern across all store implementations.
//!
//! # Usage
//!
//! ```ignore
//! use crate::serde_helpers::{serialize, deserialize};
//!
//! fn store_item(&self, item: &MyItem) -> Result<()> {
//!     let bytes = serialize(item)?;
//!     self.kv.put(&key, &bytes)?;
//!     Ok(())
//! }
//!
//! fn load_item(&self, key: &[u8]) -> Result<MyItem> {
//!     let bytes = self.kv.get(key)?.ok_or_else(|| StorageError::NotFound(...))?;
//!     deserialize(&bytes)
//! }
//! ```

use crate::error::{Result, StorageError};

/// Serialize a value using the canonical stemedb_core::serde module.
///
/// Maps serialization errors to [`StorageError::Serialization`].
pub fn serialize<T>(value: &T) -> Result<Vec<u8>>
where
    T: rkyv::Serialize<rkyv::ser::serializers::AllocSerializer<4096>>,
{
    stemedb_core::serde::serialize(value).map_err(|e| StorageError::Serialization(e.to_string()))
}

/// Deserialize a value using the canonical stemedb_core::serde module.
///
/// Maps deserialization errors to [`StorageError::Serialization`].
pub fn deserialize<T>(data: &[u8]) -> Result<T>
where
    T: rkyv::Archive,
    T::Archived: for<'a> rkyv::CheckBytes<rkyv::validation::validators::DefaultValidator<'a>>
        + rkyv::Deserialize<T, rkyv::Infallible>,
{
    stemedb_core::serde::deserialize(data).map_err(|e| StorageError::Serialization(e.to_string()))
}

#[cfg(test)]
mod tests {
    use super::*;

    #[derive(Debug, PartialEq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
    #[archive(check_bytes)]
    struct TestItem {
        id: u64,
        name: String,
    }

    #[test]
    fn test_roundtrip() {
        let item = TestItem { id: 42, name: "test".to_string() };

        let bytes = serialize(&item).expect("serialize should succeed");
        let recovered: TestItem = deserialize(&bytes).expect("deserialize should succeed");

        assert_eq!(item, recovered);
    }

    #[test]
    fn test_deserialize_invalid_data() {
        let garbage = vec![0xFF, 0xFE, 0xFD];
        let result: Result<TestItem> = deserialize(&garbage);

        assert!(result.is_err());
        let err = result.unwrap_err();
        assert!(matches!(err, StorageError::Serialization(_)));
    }
}
