train_station/serialization/core/traits.rs
1//! Core traits for serialization operations and type conversion
2//!
3//! This module defines the fundamental traits that form the backbone of the serialization
4//! system. These traits provide the interface for converting between Rust types and
5//! serializable field values, enabling type-safe serialization and deserialization
6//! with compile-time guarantees.
7//!
8//! # Purpose
9//!
10//! The traits module provides:
11//! - **Type conversion traits**: `ToFieldValue` and `FromFieldValue` for automatic type handling
12//! - **Struct serialization trait**: `StructSerializable` for complete struct serialization
13//! - **Zero-dependency design**: No external dependencies, pure Rust implementation
14//! - **Compile-time safety**: Type-safe conversions with compile-time validation
15//! - **Extensible interface**: Easy to implement for custom types
16//! - **Dual format support**: JSON and binary serialization through unified traits
17//!
18//! # Core Traits
19//!
20//! ## ToFieldValue
21//! Converts Rust types to `FieldValue` for serialization. Provides automatic type
22//! detection and conversion without requiring specialized serialization methods.
23//!
24//! ## FromFieldValue
25//! Converts `FieldValue` back to concrete Rust types during deserialization.
26//! Ensures type safety and provides detailed error reporting for conversion failures.
27//!
28//! ## StructSerializable
29//! Complete trait for struct serialization and deserialization. Provides both
30//! manual field-by-field control and convenient file I/O operations.
31//!
32//! # Implementation Patterns
33//!
34//! The traits are designed to work together seamlessly:
35//!
36//! - **Automatic conversion**: `ToFieldValue` enables generic serialization
37//! - **Type safety**: `FromFieldValue` ensures correct type reconstruction
38//! - **Complete workflow**: `StructSerializable` provides end-to-end serialization
39//! - **Error handling**: All traits return `SerializationResult` for robust error handling
40//!
41//! # Thread Safety
42//!
43//! All traits are designed to be thread-safe. Implementations should ensure that
44//! trait methods can be called concurrently without data races.
45
46use super::error::SerializationResult;
47use super::types::FieldValue;
48use std::path::Path;
49
50/// Trait for converting values to FieldValue for serialization
51///
52/// This trait provides the foundation for automatic type conversion during serialization.
53/// It allows the `StructSerializer` to handle different types generically without
54/// requiring specialized methods for each type. The conversion should be lossless
55/// and reversible to ensure data integrity.
56///
57/// # Purpose
58///
59/// The `ToFieldValue` trait enables:
60/// - **Generic serialization**: Single interface for all serializable types
61/// - **Type safety**: Compile-time guarantees for conversion correctness
62/// - **Automatic detection**: No manual type specification required
63/// - **Extensibility**: Easy to implement for custom types
64/// - **Performance**: Zero-cost abstractions for type conversion
65///
66/// # Required Methods
67///
68/// * `to_field_value` - Convert the value to a `FieldValue` for serialization
69///
70/// # Examples
71///
72/// The trait enables automatic type conversion for serialization with compile-time safety.
73///
74/// # Implementors
75///
76/// Common types that implement this trait include:
77/// * **Primitive types**: `bool`, `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`, `usize`, `f32`, `f64`
78/// * **String types**: `String`, `&str`
79/// * **Collections**: `Vec<T>`, `HashMap<String, String>`, `Option<T>`
80/// * **Custom types**: Any type implementing `ToFieldValue`
81///
82/// # Thread Safety
83///
84/// Implementations should be thread-safe and not modify any shared state during conversion.
85pub trait ToFieldValue {
86 /// Converts the value to a FieldValue for serialization
87 ///
88 /// This method should convert the implementing type into the appropriate
89 /// `FieldValue` variant. The conversion should be lossless and reversible
90 /// to ensure data integrity during serialization and deserialization cycles.
91 ///
92 /// # Returns
93 ///
94 /// A `FieldValue` representing the serialized form of the value
95 ///
96 /// # Examples
97 ///
98 /// Converts various types to their serializable representation with automatic type detection.
99 fn to_field_value(&self) -> FieldValue;
100}
101
102/// Trait for converting FieldValue back to concrete types during deserialization
103///
104/// This trait provides the foundation for automatic type reconstruction during
105/// deserialization. It allows the `StructDeserializer` to handle different types
106/// generically while ensuring type safety and providing detailed error reporting
107/// for conversion failures.
108///
109/// # Purpose
110///
111/// The `FromFieldValue` trait enables:
112/// - **Generic deserialization**: Single interface for all deserializable types
113/// - **Type safety**: Compile-time guarantees for conversion correctness
114/// - **Error handling**: Detailed error reporting for conversion failures
115/// - **Extensibility**: Easy to implement for custom types
116/// - **Validation**: Runtime type checking and validation
117///
118/// # Required Methods
119///
120/// * `from_field_value` - Convert a `FieldValue` to the concrete type
121///
122/// # Examples
123///
124/// The trait enables automatic type reconstruction during deserialization with error handling.
125///
126/// # Implementors
127///
128/// Common types that implement this trait include:
129/// * **Primitive types**: `bool`, `i8`, `i16`, `i32`, `i64`, `u8`, `u16`, `u32`, `u64`, `usize`, `f32`, `f64`
130/// * **String types**: `String`
131/// * **Collections**: `Vec<T>`, `HashMap<String, String>`, `Option<T>`
132/// * **Custom types**: Any type implementing `FromFieldValue`
133///
134/// # Thread Safety
135///
136/// Implementations should be thread-safe and not modify any shared state during conversion.
137pub trait FromFieldValue: Sized {
138 /// Converts a FieldValue to the concrete type
139 ///
140 /// This method should convert the `FieldValue` into the implementing type.
141 /// If the `FieldValue` variant doesn't match the expected type, an error
142 /// should be returned with descriptive information including the field name
143 /// for debugging purposes.
144 ///
145 /// # Arguments
146 ///
147 /// * `value` - The `FieldValue` to convert
148 /// * `field_name` - Name of the field being converted (for error reporting)
149 ///
150 /// # Returns
151 ///
152 /// `Ok(Self)` on successful conversion
153 /// `Err(SerializationError)` if the conversion fails
154 ///
155 /// # Examples
156 ///
157 /// Handles type conversion with proper error reporting and field name context.
158 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self>;
159}
160
161/// Trait for structs that can be serialized and deserialized using the struct builder pattern
162///
163/// This trait provides a complete serialization and deserialization interface for
164/// structs, offering both manual field-by-field control and convenient file I/O
165/// operations. It serves as a zero-dependency alternative to serde's derive macros,
166/// allowing structs to be easily serialized and deserialized with minimal boilerplate.
167///
168/// # Purpose
169///
170/// The `StructSerializable` trait provides:
171/// - **Complete serialization workflow**: From struct to multiple output formats
172/// - **File I/O operations**: Direct save/load to JSON and binary files
173/// - **String/binary conversion**: In-memory serialization and deserialization
174/// - **Type safety**: Compile-time guarantees for struct serialization
175/// - **Error handling**: Comprehensive error reporting for all operations
176/// - **Zero dependencies**: Pure Rust implementation without external crates
177///
178/// # Required Methods
179///
180/// * `to_serializer` - Convert the struct to a `StructSerializer`
181/// * `from_deserializer` - Create the struct from a `StructDeserializer`
182///
183/// # Provided Methods
184///
185/// * `save_json` - Save the struct to a JSON file
186/// * `save_binary` - Save the struct to a binary file
187/// * `load_json` - Load the struct from a JSON file
188/// * `load_binary` - Load the struct from a binary file
189/// * `to_json` - Convert the struct to a JSON string
190/// * `to_binary` - Convert the struct to binary data
191/// * `from_json` - Create the struct from a JSON string
192/// * `from_binary` - Create the struct from binary data
193///
194/// # Examples
195///
196/// The trait provides comprehensive serialization capabilities with file I/O and format conversion.
197///
198/// # Implementors
199///
200/// Common types that implement this trait include:
201/// * **Configuration structs**: Settings, config files, parameters
202/// * **Data models**: Business logic entities, domain objects
203/// * **Serializable objects**: Any struct requiring persistence
204/// * **Custom types**: User-defined serializable structures
205///
206/// # Thread Safety
207///
208/// Implementations should be thread-safe. The trait methods should not modify
209/// any shared state and should be safe to call concurrently.
210pub trait StructSerializable: Sized {
211 /// Converts the struct to a StructSerializer
212 ///
213 /// This method should create a `StructSerializer` and register all fields
214 /// that should be serialized. The implementation should use the fluent
215 /// interface to build the serializer with all relevant fields.
216 ///
217 /// # Returns
218 ///
219 /// A `StructSerializer` containing all the struct's serializable fields
220 ///
221 /// # Examples
222 ///
223 /// Creates a serializer with all struct fields using the fluent interface.
224 fn to_serializer(&self) -> crate::serialization::core::StructSerializer;
225
226 /// Creates the struct from a StructDeserializer
227 ///
228 /// This method should extract all fields from the deserializer and
229 /// construct a new instance of the struct. It should handle field
230 /// extraction errors gracefully and provide meaningful error messages.
231 ///
232 /// # Arguments
233 ///
234 /// * `deserializer` - The deserializer containing the struct's field data
235 ///
236 /// # Returns
237 ///
238 /// `Ok(Self)` on successful struct construction
239 /// `Err(SerializationError)` if field extraction or construction fails
240 ///
241 /// # Examples
242 ///
243 /// Extracts fields and constructs the struct with proper error handling.
244 fn from_deserializer(
245 deserializer: &mut crate::serialization::core::StructDeserializer,
246 ) -> SerializationResult<Self>;
247
248 /// Saves the struct to a JSON file
249 ///
250 /// Serializes the struct to JSON format and writes it to the specified file path.
251 /// The file is created if it doesn't exist, or truncated if it already exists.
252 ///
253 /// # Arguments
254 ///
255 /// * `path` - File path where the JSON data should be written
256 ///
257 /// # Returns
258 ///
259 /// `Ok(())` on successful file write
260 /// `Err(SerializationError)` if serialization or file I/O fails
261 ///
262 /// # Examples
263 ///
264 /// Saves struct data to a JSON file with proper file I/O handling.
265 fn save_json<P: AsRef<Path>>(&self, path: P) -> SerializationResult<()> {
266 self.to_serializer().save_json(path)
267 }
268
269 /// Saves the struct to a binary file
270 ///
271 /// Serializes the struct to binary format and writes it to the specified file path.
272 /// The file is created if it doesn't exist, or truncated if it already exists.
273 ///
274 /// # Arguments
275 ///
276 /// * `path` - File path where the binary data should be written
277 ///
278 /// # Returns
279 ///
280 /// `Ok(())` on successful file write
281 /// `Err(SerializationError)` if serialization or file I/O fails
282 ///
283 /// # Examples
284 ///
285 /// Saves struct data to a binary file with proper file I/O handling.
286 fn save_binary<P: AsRef<Path>>(&self, path: P) -> SerializationResult<()> {
287 self.to_serializer().save_binary(path)
288 }
289
290 /// Loads the struct from a JSON file
291 ///
292 /// Reads JSON data from the specified file path and deserializes it into
293 /// a new instance of the struct.
294 ///
295 /// # Arguments
296 ///
297 /// * `path` - File path containing the JSON data to read
298 ///
299 /// # Returns
300 ///
301 /// `Ok(Self)` on successful deserialization
302 /// `Err(SerializationError)` if file I/O or deserialization fails
303 ///
304 /// # Examples
305 ///
306 /// Loads struct data from a JSON file with proper error handling.
307 fn load_json<P: AsRef<Path>>(path: P) -> SerializationResult<Self> {
308 let mut deserializer = crate::serialization::core::StructDeserializer::load_json(path)?;
309 Self::from_deserializer(&mut deserializer)
310 }
311
312 /// Loads the struct from a binary file
313 ///
314 /// Reads binary data from the specified file path and deserializes it into
315 /// a new instance of the struct.
316 ///
317 /// # Arguments
318 ///
319 /// * `path` - File path containing the binary data to read
320 ///
321 /// # Returns
322 ///
323 /// `Ok(Self)` on successful deserialization
324 /// `Err(SerializationError)` if file I/O or deserialization fails
325 ///
326 /// # Examples
327 ///
328 /// Loads struct data from a binary file with proper error handling.
329 fn load_binary<P: AsRef<Path>>(path: P) -> SerializationResult<Self> {
330 let mut deserializer = crate::serialization::core::StructDeserializer::load_binary(path)?;
331 Self::from_deserializer(&mut deserializer)
332 }
333
334 /// Converts the struct to a JSON string
335 ///
336 /// Serializes the struct to a human-readable JSON string format.
337 /// The JSON output maintains field order and includes proper escaping.
338 ///
339 /// # Returns
340 ///
341 /// `Ok(String)` containing the JSON representation on success
342 /// `Err(SerializationError)` if serialization fails
343 ///
344 /// # Examples
345 ///
346 /// Converts struct to JSON string with proper escaping and formatting.
347 fn to_json(&self) -> SerializationResult<String> {
348 self.to_serializer().to_json()
349 }
350
351 /// Converts the struct to binary data
352 ///
353 /// Serializes the struct to a compact binary format optimized for
354 /// efficient storage and transmission.
355 ///
356 /// # Returns
357 ///
358 /// `Ok(Vec<u8>)` containing the binary representation on success
359 /// `Err(SerializationError)` if serialization fails
360 ///
361 /// # Examples
362 ///
363 /// Converts struct to binary data with efficient compact format.
364 fn to_binary(&self) -> SerializationResult<Vec<u8>> {
365 self.to_serializer().to_binary()
366 }
367
368 /// Creates the struct from a JSON string
369 ///
370 /// Deserializes a JSON string into a new instance of the struct.
371 /// The JSON should contain all required fields in the expected format.
372 ///
373 /// # Arguments
374 ///
375 /// * `json` - JSON string containing the struct data
376 ///
377 /// # Returns
378 ///
379 /// `Ok(Self)` on successful deserialization
380 /// `Err(SerializationError)` if JSON parsing or deserialization fails
381 ///
382 /// # Examples
383 ///
384 /// Creates struct from JSON string with proper parsing and validation.
385 fn from_json(json: &str) -> SerializationResult<Self> {
386 let mut deserializer = crate::serialization::core::StructDeserializer::from_json(json)?;
387 Self::from_deserializer(&mut deserializer)
388 }
389
390 /// Creates the struct from binary data
391 ///
392 /// Deserializes binary data into a new instance of the struct.
393 /// The binary data should contain all required fields in the expected format.
394 ///
395 /// # Arguments
396 ///
397 /// * `data` - Binary data containing the struct data
398 ///
399 /// # Returns
400 ///
401 /// `Ok(Self)` on successful deserialization
402 /// `Err(SerializationError)` if binary parsing or deserialization fails
403 ///
404 /// # Examples
405 ///
406 /// Creates struct from binary data with proper parsing and validation.
407 fn from_binary(data: &[u8]) -> SerializationResult<Self> {
408 let mut deserializer = crate::serialization::core::StructDeserializer::from_binary(data)?;
409 Self::from_deserializer(&mut deserializer)
410 }
411}