Skip to main content

reinhardt_auth/sessions/
serialization.rs

1//! Multiple serialization format support for sessions
2//!
3//! This module provides support for different serialization formats
4//! including JSON, MessagePack, CBOR, and Bincode.
5//!
6//! ## Available Serializers
7//!
8//! - **JSON** (always available): Human-readable, widely compatible
9//! - **MessagePack** (feature: `messagepack`): Compact binary format, cross-platform
10//! - **CBOR** (feature: `cbor`): RFC 7049 compliant, cross-platform
11//! - **Bincode** (feature: `bincode`): Fastest for Rust-to-Rust communication
12//!
13//! ## Example
14//!
15//! ```rust
16//! use reinhardt_auth::sessions::serialization::{Serializer, JsonSerializer};
17//! use serde_json::json;
18//!
19//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
20//! let serializer = JsonSerializer;
21//!
22//! let data = json!({
23//!     "user_id": 42,
24//!     "username": "alice",
25//! });
26//!
27//! // Serialize to bytes
28//! let bytes = serializer.serialize(&data)?;
29//!
30//! // Deserialize back
31//! let restored: serde_json::Value = serializer.deserialize(&bytes)?;
32//! assert_eq!(restored["user_id"], 42);
33//! # Ok(())
34//! # }
35//! ```
36
37use serde::{Deserialize, Serialize};
38use thiserror::Error;
39
40// Submodules
41mod json;
42pub use json::JsonSerializer;
43
44#[cfg(feature = "messagepack")]
45mod messagepack;
46#[cfg(feature = "messagepack")]
47pub use messagepack::MessagePackSerializer;
48
49#[cfg(feature = "cbor")]
50mod cbor;
51#[cfg(feature = "cbor")]
52pub use cbor::CborSerializer;
53
54#[cfg(feature = "bincode")]
55mod bincode;
56#[cfg(feature = "bincode")]
57pub use self::bincode::BincodeSerializer;
58
59/// Serialization errors
60#[non_exhaustive]
61#[derive(Debug, Error)]
62pub enum SerializationError {
63	/// JSON serialization error
64	#[error("JSON error: {0}")]
65	JsonError(#[from] serde_json::Error),
66
67	/// MessagePack serialization error
68	#[cfg(feature = "messagepack")]
69	#[error("MessagePack error: {0}")]
70	MessagePackError(#[from] rmp_serde::encode::Error),
71
72	/// MessagePack deserialization error
73	#[cfg(feature = "messagepack")]
74	#[error("MessagePack decode error: {0}")]
75	MessagePackDecodeError(#[from] rmp_serde::decode::Error),
76
77	/// Generic serialization failure
78	#[error("Serialization failed: {0}")]
79	SerializationFailed(String),
80
81	/// Generic deserialization failure
82	#[error("Deserialization failed: {0}")]
83	DeserializationFailed(String),
84
85	/// Unsupported format
86	#[error("Unsupported serialization format")]
87	UnsupportedFormat,
88}
89
90/// Serializer trait for different formats
91///
92/// # Example
93///
94/// ```rust
95/// use reinhardt_auth::sessions::serialization::{Serializer, JsonSerializer};
96/// use serde::{Serialize, Deserialize};
97///
98/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
99/// struct UserData {
100///     id: i32,
101///     name: String,
102/// }
103///
104/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
105/// let serializer = JsonSerializer;
106/// let user = UserData { id: 1, name: "Alice".to_string() };
107///
108/// let bytes = serializer.serialize(&user)?;
109/// let restored: UserData = serializer.deserialize(&bytes)?;
110///
111/// assert_eq!(user, restored);
112/// # Ok(())
113/// # }
114/// ```
115pub trait Serializer: Send + Sync {
116	/// Serialize data to bytes
117	fn serialize<T: Serialize>(&self, data: &T) -> Result<Vec<u8>, SerializationError>;
118
119	/// Deserialize bytes to data
120	fn deserialize<T: for<'de> Deserialize<'de>>(
121		&self,
122		bytes: &[u8],
123	) -> Result<T, SerializationError>;
124}
125
126/// Serialization format enum
127///
128/// # Example
129///
130/// ```rust
131/// use reinhardt_auth::sessions::serialization::SerializationFormat;
132///
133/// let format = SerializationFormat::Json;
134/// assert_eq!(format.name(), "json");
135/// ```
136#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137pub enum SerializationFormat {
138	/// JSON format (always available)
139	Json,
140	/// MessagePack format (requires "messagepack" feature)
141	#[cfg(feature = "messagepack")]
142	MessagePack,
143	/// CBOR format (requires "cbor" feature)
144	#[cfg(feature = "cbor")]
145	Cbor,
146	/// Bincode format (requires "bincode" feature)
147	#[cfg(feature = "bincode")]
148	Bincode,
149}
150
151impl SerializationFormat {
152	/// Get format name as string
153	///
154	/// # Example
155	///
156	/// ```rust
157	/// use reinhardt_auth::sessions::serialization::SerializationFormat;
158	///
159	/// assert_eq!(SerializationFormat::Json.name(), "json");
160	/// ```
161	pub fn name(&self) -> &'static str {
162		match self {
163			SerializationFormat::Json => "json",
164			#[cfg(feature = "messagepack")]
165			SerializationFormat::MessagePack => "messagepack",
166			#[cfg(feature = "cbor")]
167			SerializationFormat::Cbor => "cbor",
168			#[cfg(feature = "bincode")]
169			SerializationFormat::Bincode => "bincode",
170		}
171	}
172
173	/// Serialize data using this format
174	///
175	/// # Example
176	///
177	/// ```rust
178	/// use reinhardt_auth::sessions::serialization::SerializationFormat;
179	/// use serde_json::json;
180	///
181	/// # fn example() -> Result<(), Box<dyn std::error::Error>> {
182	/// let format = SerializationFormat::Json;
183	///
184	/// let data = json!({"test": true});
185	/// let bytes = format.serialize(&data)?;
186	/// let restored: serde_json::Value = format.deserialize(&bytes)?;
187	///
188	/// assert_eq!(restored["test"], true);
189	/// # Ok(())
190	/// # }
191	/// ```
192	pub fn serialize<T: Serialize>(&self, data: &T) -> Result<Vec<u8>, SerializationError> {
193		match self {
194			SerializationFormat::Json => JsonSerializer.serialize(data),
195			#[cfg(feature = "messagepack")]
196			SerializationFormat::MessagePack => MessagePackSerializer.serialize(data),
197			#[cfg(feature = "cbor")]
198			SerializationFormat::Cbor => CborSerializer.serialize(data),
199			#[cfg(feature = "bincode")]
200			SerializationFormat::Bincode => BincodeSerializer.serialize(data),
201		}
202	}
203
204	/// Deserialize data using this format
205	pub fn deserialize<T: for<'de> Deserialize<'de>>(
206		&self,
207		bytes: &[u8],
208	) -> Result<T, SerializationError> {
209		match self {
210			SerializationFormat::Json => JsonSerializer.deserialize(bytes),
211			#[cfg(feature = "messagepack")]
212			SerializationFormat::MessagePack => MessagePackSerializer.deserialize(bytes),
213			#[cfg(feature = "cbor")]
214			SerializationFormat::Cbor => CborSerializer.deserialize(bytes),
215			#[cfg(feature = "bincode")]
216			SerializationFormat::Bincode => BincodeSerializer.deserialize(bytes),
217		}
218	}
219}
220
221impl Default for SerializationFormat {
222	/// Default serialization format is JSON
223	///
224	/// # Example
225	///
226	/// ```rust
227	/// use reinhardt_auth::sessions::serialization::SerializationFormat;
228	///
229	/// let format = SerializationFormat::default();
230	/// assert_eq!(format, SerializationFormat::Json);
231	/// ```
232	fn default() -> Self {
233		Self::Json
234	}
235}
236
237#[cfg(test)]
238mod tests {
239	use super::*;
240
241	#[test]
242	fn test_serialization_format_name() {
243		assert_eq!(SerializationFormat::Json.name(), "json");
244
245		#[cfg(feature = "messagepack")]
246		assert_eq!(SerializationFormat::MessagePack.name(), "messagepack");
247
248		#[cfg(feature = "cbor")]
249		assert_eq!(SerializationFormat::Cbor.name(), "cbor");
250
251		#[cfg(feature = "bincode")]
252		assert_eq!(SerializationFormat::Bincode.name(), "bincode");
253	}
254
255	#[test]
256	fn test_serialization_format_default() {
257		let format = SerializationFormat::default();
258		assert_eq!(format, SerializationFormat::Json);
259	}
260
261	#[test]
262	fn test_serialization_format_serialize_deserialize() {
263		let format = SerializationFormat::Json;
264
265		let data = serde_json::json!({"test": "value"});
266		let bytes = format.serialize(&data).unwrap();
267		let restored: serde_json::Value = format.deserialize(&bytes).unwrap();
268
269		assert_eq!(restored["test"], "value");
270	}
271}