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}