Skip to main content

icydb_core/serialize/
mod.rs

1//! Module: serialize
2//!
3//! Responsibility: module-local ownership and contracts for serialize.
4//! Does not own: cross-module orchestration outside this module.
5//! Boundary: exposes this module API while keeping implementation details internal.
6
7mod cbor;
8
9use serde::{Serialize, de::DeserializeOwned};
10use std::fmt;
11use thiserror::Error as ThisError;
12
13/// Generic CBOR serialization infrastructure.
14///
15/// This module is format-level only:
16/// - No database-layer constants or policy limits are defined here.
17/// - Callers that need bounded decode must pass explicit limits.
18/// - Engine-specific decode policy belongs in subsystem wrappers (for example, `db::codec`).
19
20///
21/// SerializeError
22///
23
24#[derive(Debug, ThisError)]
25pub enum SerializeError {
26    #[error("serialize error: {0}")]
27    Serialize(String),
28
29    #[error("deserialize error: {0}")]
30    Deserialize(String),
31
32    #[error("deserialize size limit exceeded: {len} bytes (limit {max_bytes})")]
33    DeserializeSizeLimitExceeded { len: usize, max_bytes: usize },
34}
35
36///
37/// SerializeErrorKind
38///
39/// Stable error-kind taxonomy for serializer failures.
40///
41
42#[derive(Clone, Copy, Debug, Eq, PartialEq)]
43pub enum SerializeErrorKind {
44    Serialize,
45    Deserialize,
46    DeserializeSizeLimitExceeded,
47}
48
49impl SerializeErrorKind {
50    #[must_use]
51    pub const fn as_str(self) -> &'static str {
52        match self {
53            Self::Serialize => "serialize",
54            Self::Deserialize => "deserialize",
55            Self::DeserializeSizeLimitExceeded => "deserialize_size_limit_exceeded",
56        }
57    }
58}
59
60impl fmt::Display for SerializeErrorKind {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        f.write_str(self.as_str())
63    }
64}
65
66impl SerializeError {
67    /// Return a stable error kind independent of backend error-message text.
68    #[must_use]
69    pub const fn kind(&self) -> SerializeErrorKind {
70        match self {
71            Self::Serialize(_) => SerializeErrorKind::Serialize,
72            Self::Deserialize(_) => SerializeErrorKind::Deserialize,
73            Self::DeserializeSizeLimitExceeded { .. } => {
74                SerializeErrorKind::DeserializeSizeLimitExceeded
75            }
76        }
77    }
78}
79
80/// Serialize a value using the default `canic` serializer.
81///
82/// This helper keeps the error type aligned with the rest of `icydb`.
83pub fn serialize<T>(ty: &T) -> Result<Vec<u8>, SerializeError>
84where
85    T: Serialize,
86{
87    cbor::serialize(ty)
88}
89
90/// Return serialized byte length using the default `canic` serializer without
91/// allocating an output buffer.
92pub fn serialized_len<T>(ty: &T) -> Result<usize, SerializeError>
93where
94    T: Serialize,
95{
96    cbor::serialize_len(ty)
97}
98
99/// Deserialize a value produced by [`serialize`].
100pub fn deserialize<T>(bytes: &[u8]) -> Result<T, SerializeError>
101where
102    T: DeserializeOwned,
103{
104    cbor::deserialize(bytes)
105}
106
107/// Deserialize a value produced by [`serialize`], with an explicit size limit.
108///
109/// Size limits are caller policy, not serialization-format policy.
110pub fn deserialize_bounded<T>(bytes: &[u8], max_bytes: usize) -> Result<T, SerializeError>
111where
112    T: DeserializeOwned,
113{
114    cbor::deserialize_bounded(bytes, max_bytes)
115}