pub struct StructDeserializer { /* private fields */ }Expand description
Deserializer for structured data extraction and type conversion
This struct provides a type-safe interface for deserializing complex structures
that were created with StructSerializer. It supports both JSON and binary
formats, with comprehensive error handling and flexible field access patterns.
The deserializer maintains a HashMap of field names to FieldValue instances,
allowing for efficient field lookup and extraction. Fields are consumed during
extraction to prevent accidental reuse and ensure proper deserialization flow.
§Fields
fields- Internal storage mapping field names to their serialized values
§Thread Safety
This type is not thread-safe. Access from multiple threads requires external synchronization.
§Memory Layout
The deserializer uses a HashMap for field storage, providing O(1) average field lookup time. Memory usage scales linearly with the number of fields.
Implementations§
Source§impl StructDeserializer
impl StructDeserializer
Sourcepub fn from_fields(fields: HashMap<String, FieldValue>) -> Self
pub fn from_fields(fields: HashMap<String, FieldValue>) -> Self
Create a new StructDeserializer from a field map
This is the recommended way to create a StructDeserializer when you have
a HashMap of fields, typically from a FieldValue::Object variant or when
constructing a deserializer programmatically.
§Arguments
fields- HashMap containing field names and their serialized values
§Returns
A new StructDeserializer ready for field extraction
§Performance
This constructor performs no validation or conversion, making it the fastest way to create a deserializer when you already have the field data.
Sourcepub fn load_json<P: AsRef<Path>>(path: P) -> SerializationResult<Self>
pub fn load_json<P: AsRef<Path>>(path: P) -> SerializationResult<Self>
Load a struct from a JSON file
Reads a JSON file from the filesystem and creates a StructDeserializer from its contents. The file is expected to contain a valid JSON object that can be parsed into field-value pairs.
§Arguments
path- Path to the JSON file to load
§Returns
A StructDeserializer containing the parsed field data, or an error if the file cannot be read or parsed
§Errors
Returns an error if:
- The file does not exist or cannot be opened
- The file contains invalid JSON
- The JSON structure is not a valid object
- I/O errors occur during file reading
§Performance
The entire file is read into memory before parsing. For very large files, consider using streaming JSON parsing instead.
Sourcepub fn load_binary<P: AsRef<Path>>(path: P) -> SerializationResult<Self>
pub fn load_binary<P: AsRef<Path>>(path: P) -> SerializationResult<Self>
Load a struct from a binary file
Reads a binary file from the filesystem and creates a StructDeserializer from its contents. The file is expected to contain valid binary data that was previously serialized using the binary format.
§Arguments
path- Path to the binary file to load
§Returns
A StructDeserializer containing the parsed field data, or an error if the file cannot be read or parsed
§Errors
Returns an error if:
- The file does not exist or cannot be opened
- The file contains invalid binary format
- The binary data is corrupted or truncated
- I/O errors occur during file reading
§Performance
The entire file is read into memory before parsing. Binary format is typically more compact and faster to parse than JSON.
Sourcepub fn field<T: FromFieldValue>(&mut self, name: &str) -> SerializationResult<T>
pub fn field<T: FromFieldValue>(&mut self, name: &str) -> SerializationResult<T>
Extract a field with automatic type detection
Extracts a field from the deserializer and converts it to the specified type. The field is consumed (removed) from the deserializer to prevent accidental reuse and ensure proper deserialization flow.
§Arguments
name- Name of the field to extract
§Returns
The converted field value, or an error if the field is missing or cannot be converted to the target type
§Errors
Returns an error if:
- The field does not exist in the deserializer
- The field value cannot be converted to the target type
- Type conversion fails due to incompatible data
§Performance
Field extraction is O(1) average case due to HashMap lookup. The field is removed from the deserializer to prevent memory leaks.
Examples found in repository?
56 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
57 let email = deserializer.field("email")?;
58 let phone = deserializer.field("phone")?;
59 let address_city = deserializer.field("address_city")?;
60 let address_state = deserializer.field("address_state")?;
61 let social_media = deserializer.field("social_media")?;
62
63 Ok(ContactInfo {
64 email,
65 phone,
66 address_city,
67 address_state,
68 social_media,
69 })
70 }
71}
72
73impl ToFieldValue for ContactInfo {
74 fn to_field_value(&self) -> FieldValue {
75 match self.to_json() {
76 Ok(json_str) => FieldValue::from_json_object(json_str),
77 Err(_) => FieldValue::from_string("serialization_error".to_string()),
78 }
79 }
80}
81
82impl FromFieldValue for ContactInfo {
83 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
84 // Try JSON object first
85 if let Ok(json_data) = value.as_json_object() {
86 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
87 field: field_name.to_string(),
88 message: format!("Failed to deserialize ContactInfo from JSON: {}", e),
89 });
90 }
91
92 // Try binary object
93 if let Ok(binary_data) = value.as_binary_object() {
94 return Self::from_binary(binary_data).map_err(|e| {
95 SerializationError::ValidationFailed {
96 field: field_name.to_string(),
97 message: format!("Failed to deserialize ContactInfo from binary: {}", e),
98 }
99 });
100 }
101
102 Err(SerializationError::ValidationFailed {
103 field: field_name.to_string(),
104 message: format!(
105 "Expected JsonObject or BinaryObject for ContactInfo, found {}",
106 value.type_name()
107 ),
108 })
109 }
110}
111
112/// Address struct
113#[derive(Debug, Clone, PartialEq)]
114pub struct Address {
115 pub street: String,
116 pub city: String,
117 pub state: String,
118 pub postal_code: String,
119 pub country: String,
120}
121
122impl StructSerializable for Address {
123 fn to_serializer(&self) -> StructSerializer {
124 StructSerializer::new()
125 .field("street", &self.street)
126 .field("city", &self.city)
127 .field("state", &self.state)
128 .field("postal_code", &self.postal_code)
129 .field("country", &self.country)
130 }
131
132 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
133 let street = deserializer.field("street")?;
134 let city = deserializer.field("city")?;
135 let state = deserializer.field("state")?;
136 let postal_code = deserializer.field("postal_code")?;
137 let country = deserializer.field("country")?;
138
139 Ok(Address {
140 street,
141 city,
142 state,
143 postal_code,
144 country,
145 })
146 }
147}
148
149impl ToFieldValue for Address {
150 fn to_field_value(&self) -> FieldValue {
151 match self.to_json() {
152 Ok(json_str) => FieldValue::from_json_object(json_str),
153 Err(_) => FieldValue::from_string("serialization_error".to_string()),
154 }
155 }
156}
157
158impl FromFieldValue for Address {
159 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
160 // Try JSON object first
161 if let Ok(json_data) = value.as_json_object() {
162 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
163 field: field_name.to_string(),
164 message: format!("Failed to deserialize Address from JSON: {}", e),
165 });
166 }
167
168 // Try binary object
169 if let Ok(binary_data) = value.as_binary_object() {
170 return Self::from_binary(binary_data).map_err(|e| {
171 SerializationError::ValidationFailed {
172 field: field_name.to_string(),
173 message: format!("Failed to deserialize Address from binary: {}", e),
174 }
175 });
176 }
177
178 Err(SerializationError::ValidationFailed {
179 field: field_name.to_string(),
180 message: format!(
181 "Expected JsonObject or BinaryObject for Address, found {}",
182 value.type_name()
183 ),
184 })
185 }
186}
187
188/// Project information struct
189#[derive(Debug, Clone, PartialEq)]
190pub struct Project {
191 pub name: String,
192 pub description: String,
193 pub status: ProjectStatus,
194 pub budget: f64,
195 pub team_members: Vec<String>,
196 pub milestones: Vec<Milestone>,
197 pub metadata: HashMap<String, String>,
198}
199
200impl StructSerializable for Project {
201 fn to_serializer(&self) -> StructSerializer {
202 StructSerializer::new()
203 .field("name", &self.name)
204 .field("description", &self.description)
205 .field("status", &self.status)
206 .field("budget", &self.budget)
207 .field("team_members", &self.team_members)
208 .field("milestones", &self.milestones)
209 .field("metadata", &self.metadata)
210 }
211
212 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
213 let name = deserializer.field("name")?;
214 let description = deserializer.field("description")?;
215 let status = deserializer.field("status")?;
216 let budget = deserializer.field("budget")?;
217 let team_members = deserializer.field("team_members")?;
218 let milestones = deserializer.field("milestones")?;
219 let metadata = deserializer.field("metadata")?;
220
221 Ok(Project {
222 name,
223 description,
224 status,
225 budget,
226 team_members,
227 milestones,
228 metadata,
229 })
230 }
231}
232
233impl ToFieldValue for Project {
234 fn to_field_value(&self) -> FieldValue {
235 match self.to_json() {
236 Ok(json_str) => FieldValue::from_json_object(json_str),
237 Err(_) => FieldValue::from_string("serialization_error".to_string()),
238 }
239 }
240}
241
242impl FromFieldValue for Project {
243 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
244 // Try JSON object first
245 if let Ok(json_data) = value.as_json_object() {
246 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
247 field: field_name.to_string(),
248 message: format!("Failed to deserialize Project from JSON: {}", e),
249 });
250 }
251
252 // Try binary object
253 if let Ok(binary_data) = value.as_binary_object() {
254 return Self::from_binary(binary_data).map_err(|e| {
255 SerializationError::ValidationFailed {
256 field: field_name.to_string(),
257 message: format!("Failed to deserialize Project from binary: {}", e),
258 }
259 });
260 }
261
262 Err(SerializationError::ValidationFailed {
263 field: field_name.to_string(),
264 message: format!(
265 "Expected JsonObject or BinaryObject for Project, found {}",
266 value.type_name()
267 ),
268 })
269 }
270}
271
272/// Project status enumeration
273#[derive(Debug, Clone, PartialEq)]
274pub enum ProjectStatus {
275 Planning,
276 InProgress,
277 OnHold,
278 Completed,
279 Cancelled,
280}
281
282impl ToFieldValue for ProjectStatus {
283 fn to_field_value(&self) -> FieldValue {
284 let status_str = match self {
285 ProjectStatus::Planning => "planning",
286 ProjectStatus::InProgress => "in_progress",
287 ProjectStatus::OnHold => "on_hold",
288 ProjectStatus::Completed => "completed",
289 ProjectStatus::Cancelled => "cancelled",
290 };
291 FieldValue::from_string(status_str.to_string())
292 }
293}
294
295impl FromFieldValue for ProjectStatus {
296 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
297 match value {
298 FieldValue::String(s) => match s.as_str() {
299 "planning" => Ok(ProjectStatus::Planning),
300 "in_progress" => Ok(ProjectStatus::InProgress),
301 "on_hold" => Ok(ProjectStatus::OnHold),
302 "completed" => Ok(ProjectStatus::Completed),
303 "cancelled" => Ok(ProjectStatus::Cancelled),
304 _ => Err(SerializationError::ValidationFailed {
305 field: field_name.to_string(),
306 message: format!("Unknown project status: {}", s),
307 }),
308 },
309 _ => Err(SerializationError::ValidationFailed {
310 field: field_name.to_string(),
311 message: format!(
312 "Expected String for ProjectStatus, found {}",
313 value.type_name()
314 ),
315 }),
316 }
317 }
318}
319
320/// Project milestone struct
321#[derive(Debug, Clone, PartialEq)]
322pub struct Milestone {
323 pub name: String,
324 pub description: String,
325 pub due_date: String, // Simplified as string for this example
326 pub is_completed: bool,
327 pub progress_percentage: f32,
328 pub dependencies: Vec<String>,
329}
330
331impl StructSerializable for Milestone {
332 fn to_serializer(&self) -> StructSerializer {
333 StructSerializer::new()
334 .field("name", &self.name)
335 .field("description", &self.description)
336 .field("due_date", &self.due_date)
337 .field("is_completed", &self.is_completed)
338 .field("progress_percentage", &self.progress_percentage)
339 .field("dependencies", &self.dependencies)
340 }
341
342 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
343 let name = deserializer.field("name")?;
344 let description = deserializer.field("description")?;
345 let due_date = deserializer.field("due_date")?;
346 let is_completed = deserializer.field("is_completed")?;
347 let progress_percentage = deserializer.field("progress_percentage")?;
348 let dependencies = deserializer.field("dependencies")?;
349
350 Ok(Milestone {
351 name,
352 description,
353 due_date,
354 is_completed,
355 progress_percentage,
356 dependencies,
357 })
358 }
359}
360
361impl ToFieldValue for Milestone {
362 fn to_field_value(&self) -> FieldValue {
363 match self.to_json() {
364 Ok(json_str) => FieldValue::from_json_object(json_str),
365 Err(_) => FieldValue::from_string("serialization_error".to_string()),
366 }
367 }
368}
369
370impl FromFieldValue for Milestone {
371 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
372 // Try JSON object first
373 if let Ok(json_data) = value.as_json_object() {
374 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
375 field: field_name.to_string(),
376 message: format!("Failed to deserialize Milestone from JSON: {}", e),
377 });
378 }
379
380 // Try binary object
381 if let Ok(binary_data) = value.as_binary_object() {
382 return Self::from_binary(binary_data).map_err(|e| {
383 SerializationError::ValidationFailed {
384 field: field_name.to_string(),
385 message: format!("Failed to deserialize Milestone from binary: {}", e),
386 }
387 });
388 }
389
390 Err(SerializationError::ValidationFailed {
391 field: field_name.to_string(),
392 message: format!(
393 "Expected JsonObject or BinaryObject for Milestone, found {}",
394 value.type_name()
395 ),
396 })
397 }
398}
399
400/// Company struct with basic collections and nesting
401#[derive(Debug, Clone, PartialEq)]
402pub struct Company {
403 pub name: String,
404 pub founded_year: i32,
405 pub headquarters_city: String,
406 pub headquarters_state: String,
407 pub employee_count: usize,
408 pub department_names: Vec<String>,
409 pub active_project_names: Vec<String>,
410 pub company_metadata: HashMap<String, String>,
411}
412
413impl StructSerializable for Company {
414 fn to_serializer(&self) -> StructSerializer {
415 StructSerializer::new()
416 .field("name", &self.name)
417 .field("founded_year", &self.founded_year)
418 .field("headquarters_city", &self.headquarters_city)
419 .field("headquarters_state", &self.headquarters_state)
420 .field("employee_count", &self.employee_count)
421 .field("department_names", &self.department_names)
422 .field("active_project_names", &self.active_project_names)
423 .field("company_metadata", &self.company_metadata)
424 }
425
426 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
427 let name = deserializer.field("name")?;
428 let founded_year = deserializer.field("founded_year")?;
429 let headquarters_city = deserializer.field("headquarters_city")?;
430 let headquarters_state = deserializer.field("headquarters_state")?;
431 let employee_count = deserializer.field("employee_count")?;
432 let department_names = deserializer.field("department_names")?;
433 let active_project_names = deserializer.field("active_project_names")?;
434 let company_metadata = deserializer.field("company_metadata")?;
435
436 Ok(Company {
437 name,
438 founded_year,
439 headquarters_city,
440 headquarters_state,
441 employee_count,
442 department_names,
443 active_project_names,
444 company_metadata,
445 })
446 }
447}
448
449impl ToFieldValue for Company {
450 fn to_field_value(&self) -> FieldValue {
451 match self.to_json() {
452 Ok(json_str) => FieldValue::from_json_object(json_str),
453 Err(_) => FieldValue::from_string("serialization_error".to_string()),
454 }
455 }
456}
457
458impl FromFieldValue for Company {
459 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
460 // Try JSON object first
461 if let Ok(json_data) = value.as_json_object() {
462 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
463 field: field_name.to_string(),
464 message: format!("Failed to deserialize Company from JSON: {}", e),
465 });
466 }
467
468 // Try binary object
469 if let Ok(binary_data) = value.as_binary_object() {
470 return Self::from_binary(binary_data).map_err(|e| {
471 SerializationError::ValidationFailed {
472 field: field_name.to_string(),
473 message: format!("Failed to deserialize Company from binary: {}", e),
474 }
475 });
476 }
477
478 Err(SerializationError::ValidationFailed {
479 field: field_name.to_string(),
480 message: format!(
481 "Expected JsonObject or BinaryObject for Company, found {}",
482 value.type_name()
483 ),
484 })
485 }
486}
487
488/// Department struct
489#[derive(Debug, Clone, PartialEq)]
490pub struct Department {
491 pub name: String,
492 pub manager: String,
493 pub employee_count: u32,
494 pub budget: f64,
495 pub office_locations: Vec<Address>,
496}
497
498impl StructSerializable for Department {
499 fn to_serializer(&self) -> StructSerializer {
500 StructSerializer::new()
501 .field("name", &self.name)
502 .field("manager", &self.manager)
503 .field("employee_count", &self.employee_count)
504 .field("budget", &self.budget)
505 .field("office_locations", &self.office_locations)
506 }
507
508 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
509 let name = deserializer.field("name")?;
510 let manager = deserializer.field("manager")?;
511 let employee_count = deserializer.field("employee_count")?;
512 let budget = deserializer.field("budget")?;
513 let office_locations = deserializer.field("office_locations")?;
514
515 Ok(Department {
516 name,
517 manager,
518 employee_count,
519 budget,
520 office_locations,
521 })
522 }More examples
58 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
59 let id = deserializer.field("id")?;
60 let username = deserializer.field("username")?;
61 let email = deserializer.field("email")?;
62 let age = deserializer.field("age")?;
63 let is_active = deserializer.field("is_active")?;
64 let score = deserializer.field("score")?;
65
66 Ok(UserProfile {
67 id,
68 username,
69 email,
70 age,
71 is_active,
72 score,
73 })
74 }
75}
76
77impl ToFieldValue for UserProfile {
78 fn to_field_value(&self) -> FieldValue {
79 // Convert to JSON and then parse as FieldValue for nested object handling
80 match self.to_json() {
81 Ok(json_str) => {
82 // For examples, we'll serialize as JSON string for simplicity
83 FieldValue::from_json_object(json_str)
84 }
85 Err(_) => FieldValue::from_string("serialization_error".to_string()),
86 }
87 }
88}
89
90impl FromFieldValue for UserProfile {
91 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
92 // Try JSON object first
93 if let Ok(json_data) = value.as_json_object() {
94 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
95 field: field_name.to_string(),
96 message: format!("Failed to deserialize UserProfile from JSON: {}", e),
97 });
98 }
99
100 // Try binary object
101 if let Ok(binary_data) = value.as_binary_object() {
102 return Self::from_binary(binary_data).map_err(|e| {
103 SerializationError::ValidationFailed {
104 field: field_name.to_string(),
105 message: format!("Failed to deserialize UserProfile from binary: {}", e),
106 }
107 });
108 }
109
110 Err(SerializationError::ValidationFailed {
111 field: field_name.to_string(),
112 message: format!(
113 "Expected JsonObject or BinaryObject for UserProfile, found {}",
114 value.type_name()
115 ),
116 })
117 }
118}
119
120/// Application settings struct with optional fields and collections
121#[derive(Debug, Clone, PartialEq)]
122pub struct AppSettings {
123 pub app_name: String,
124 pub version: String,
125 pub debug_mode: bool,
126 pub max_connections: u32,
127 pub timeout_seconds: f32,
128 pub features: Vec<String>,
129 pub environment_vars: HashMap<String, String>,
130 pub optional_database_url: Option<String>,
131}
132
133impl StructSerializable for AppSettings {
134 fn to_serializer(&self) -> StructSerializer {
135 StructSerializer::new()
136 .field("app_name", &self.app_name)
137 .field("version", &self.version)
138 .field("debug_mode", &self.debug_mode)
139 .field("max_connections", &self.max_connections)
140 .field("timeout_seconds", &self.timeout_seconds)
141 .field("features", &self.features)
142 .field("environment_vars", &self.environment_vars)
143 .field("optional_database_url", &self.optional_database_url)
144 }
145
146 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
147 let app_name = deserializer.field("app_name")?;
148 let version = deserializer.field("version")?;
149 let debug_mode = deserializer.field("debug_mode")?;
150 let max_connections = deserializer.field("max_connections")?;
151 let timeout_seconds = deserializer.field("timeout_seconds")?;
152 let features = deserializer.field("features")?;
153 let environment_vars = deserializer.field("environment_vars")?;
154 let optional_database_url = deserializer.field("optional_database_url")?;
155
156 Ok(AppSettings {
157 app_name,
158 version,
159 debug_mode,
160 max_connections,
161 timeout_seconds,
162 features,
163 environment_vars,
164 optional_database_url,
165 })
166 }58 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
59 let operation = deserializer.field("operation")?;
60 let duration_micros = deserializer.field("duration_micros")?;
61 let memory_usage_bytes = deserializer.field("memory_usage_bytes")?;
62 let cpu_usage_percent = deserializer.field("cpu_usage_percent")?;
63 let throughput_ops_per_sec = deserializer.field("throughput_ops_per_sec")?;
64 let metadata = deserializer.field("metadata")?;
65
66 Ok(PerformanceMetrics {
67 operation,
68 duration_micros,
69 memory_usage_bytes,
70 cpu_usage_percent,
71 throughput_ops_per_sec,
72 metadata,
73 })
74 }
75}
76
77impl ToFieldValue for PerformanceMetrics {
78 fn to_field_value(&self) -> FieldValue {
79 match self.to_json() {
80 Ok(json_str) => FieldValue::from_json_object(json_str),
81 Err(_) => FieldValue::from_string("serialization_error".to_string()),
82 }
83 }
84}
85
86impl FromFieldValue for PerformanceMetrics {
87 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
88 // Try JSON object first
89 if let Ok(json_data) = value.as_json_object() {
90 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
91 field: field_name.to_string(),
92 message: format!("Failed to deserialize PerformanceMetrics from JSON: {}", e),
93 });
94 }
95
96 // Try binary object
97 if let Ok(binary_data) = value.as_binary_object() {
98 return Self::from_binary(binary_data).map_err(|e| {
99 SerializationError::ValidationFailed {
100 field: field_name.to_string(),
101 message: format!(
102 "Failed to deserialize PerformanceMetrics from binary: {}",
103 e
104 ),
105 }
106 });
107 }
108
109 Err(SerializationError::ValidationFailed {
110 field: field_name.to_string(),
111 message: format!(
112 "Expected JsonObject or BinaryObject for PerformanceMetrics, found {}",
113 value.type_name()
114 ),
115 })
116 }
117}
118
119/// Large dataset for performance testing
120#[derive(Debug, Clone, PartialEq)]
121pub struct LargeDataset {
122 pub name: String,
123 pub values: Vec<f32>, // Changed from f64 to f32 (supported)
124 pub labels: Vec<String>,
125 pub feature_count: usize, // Simplified from Vec<Vec<f32>> to just a count
126 pub feature_dimension: usize, // Store dimensions separately
127 pub metadata: HashMap<String, String>,
128 pub timestamp_count: usize, // Simplified from Vec<u64> to just count
129}
130
131impl StructSerializable for LargeDataset {
132 fn to_serializer(&self) -> StructSerializer {
133 StructSerializer::new()
134 .field("name", &self.name)
135 .field("values", &self.values)
136 .field("labels", &self.labels)
137 .field("feature_count", &self.feature_count)
138 .field("feature_dimension", &self.feature_dimension)
139 .field("metadata", &self.metadata)
140 .field("timestamp_count", &self.timestamp_count)
141 }
142
143 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
144 let name = deserializer.field("name")?;
145 let values = deserializer.field("values")?;
146 let labels = deserializer.field("labels")?;
147 let feature_count = deserializer.field("feature_count")?;
148 let feature_dimension = deserializer.field("feature_dimension")?;
149 let metadata = deserializer.field("metadata")?;
150 let timestamp_count = deserializer.field("timestamp_count")?;
151
152 Ok(LargeDataset {
153 name,
154 values,
155 labels,
156 feature_count,
157 feature_dimension,
158 metadata,
159 timestamp_count,
160 })
161 }
162}
163
164impl ToFieldValue for LargeDataset {
165 fn to_field_value(&self) -> FieldValue {
166 match self.to_json() {
167 Ok(json_str) => FieldValue::from_json_object(json_str),
168 Err(_) => FieldValue::from_string("serialization_error".to_string()),
169 }
170 }
171}
172
173impl FromFieldValue for LargeDataset {
174 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
175 // Try JSON object first
176 if let Ok(json_data) = value.as_json_object() {
177 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
178 field: field_name.to_string(),
179 message: format!("Failed to deserialize LargeDataset from JSON: {}", e),
180 });
181 }
182
183 // Try binary object
184 if let Ok(binary_data) = value.as_binary_object() {
185 return Self::from_binary(binary_data).map_err(|e| {
186 SerializationError::ValidationFailed {
187 field: field_name.to_string(),
188 message: format!("Failed to deserialize LargeDataset from binary: {}", e),
189 }
190 });
191 }
192
193 Err(SerializationError::ValidationFailed {
194 field: field_name.to_string(),
195 message: format!(
196 "Expected JsonObject or BinaryObject for LargeDataset, found {}",
197 value.type_name()
198 ),
199 })
200 }
201}
202
203/// Configuration data (typical JSON use case)
204#[derive(Debug, Clone, PartialEq)]
205pub struct Configuration {
206 pub version: String,
207 pub debug_enabled: bool,
208 pub log_level: String,
209 pub database_settings: HashMap<String, String>,
210 pub feature_flags_enabled: bool, // Simplified from HashMap<String, bool>
211 pub max_connections: f32, // Simplified from HashMap<String, f64>
212 pub timeout_seconds: f32,
213}
214
215impl StructSerializable for Configuration {
216 fn to_serializer(&self) -> StructSerializer {
217 StructSerializer::new()
218 .field("version", &self.version)
219 .field("debug_enabled", &self.debug_enabled)
220 .field("log_level", &self.log_level)
221 .field("database_settings", &self.database_settings)
222 .field("feature_flags_enabled", &self.feature_flags_enabled)
223 .field("max_connections", &self.max_connections)
224 .field("timeout_seconds", &self.timeout_seconds)
225 }
226
227 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
228 let version = deserializer.field("version")?;
229 let debug_enabled = deserializer.field("debug_enabled")?;
230 let log_level = deserializer.field("log_level")?;
231 let database_settings = deserializer.field("database_settings")?;
232 let feature_flags_enabled = deserializer.field("feature_flags_enabled")?;
233 let max_connections = deserializer.field("max_connections")?;
234 let timeout_seconds = deserializer.field("timeout_seconds")?;
235
236 Ok(Configuration {
237 version,
238 debug_enabled,
239 log_level,
240 database_settings,
241 feature_flags_enabled,
242 max_connections,
243 timeout_seconds,
244 })
245 }57 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
58 let version = deserializer.field("version")?;
59 let name = deserializer.field("name")?;
60 let value = deserializer.field("value")?;
61
62 // Handle optional fields gracefully for schema evolution
63 let optional_field = deserializer.field_optional("optional_field")?;
64 let new_field = deserializer.field_optional("new_field")?;
65
66 // Validate version compatibility
67 if version > 3 {
68 return Err(SerializationError::ValidationFailed {
69 field: "version".to_string(),
70 message: format!("Unsupported version: {}. Maximum supported: 3", version),
71 });
72 }
73
74 Ok(VersionedData {
75 version,
76 name,
77 value,
78 optional_field,
79 new_field,
80 })
81 }
82}
83
84impl ToFieldValue for VersionedData {
85 fn to_field_value(&self) -> FieldValue {
86 match self.to_json() {
87 Ok(json_str) => FieldValue::from_json_object(json_str),
88 Err(_) => FieldValue::from_string("serialization_error".to_string()),
89 }
90 }
91}
92
93impl FromFieldValue for VersionedData {
94 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
95 // Try JSON object first
96 if let Ok(json_data) = value.as_json_object() {
97 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
98 field: field_name.to_string(),
99 message: format!("Failed to deserialize VersionedData from JSON: {}", e),
100 });
101 }
102
103 // Try binary object
104 if let Ok(binary_data) = value.as_binary_object() {
105 return Self::from_binary(binary_data).map_err(|e| {
106 SerializationError::ValidationFailed {
107 field: field_name.to_string(),
108 message: format!("Failed to deserialize VersionedData from binary: {}", e),
109 }
110 });
111 }
112
113 Err(SerializationError::ValidationFailed {
114 field: field_name.to_string(),
115 message: format!(
116 "Expected JsonObject or BinaryObject for VersionedData, found {}",
117 value.type_name()
118 ),
119 })
120 }
121}
122
123/// Validated user input with constraints
124#[derive(Debug, Clone, PartialEq)]
125pub struct ValidatedUserInput {
126 pub username: String,
127 pub email: String,
128 pub age: u16,
129 pub preferences: HashMap<String, String>,
130}
131
132impl StructSerializable for ValidatedUserInput {
133 fn to_serializer(&self) -> StructSerializer {
134 StructSerializer::new()
135 .field("username", &self.username)
136 .field("email", &self.email)
137 .field("age", &self.age)
138 .field("preferences", &self.preferences)
139 }
140
141 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
142 let username: String = deserializer.field("username")?;
143 let email: String = deserializer.field("email")?;
144 let age: u16 = deserializer.field("age")?;
145 let preferences: HashMap<String, String> = deserializer.field("preferences")?;
146
147 // Validate username
148 if username.is_empty() || username.len() > 50 {
149 return Err(SerializationError::ValidationFailed {
150 field: "username".to_string(),
151 message: "Username must be 1-50 characters long".to_string(),
152 });
153 }
154
155 if !username
156 .chars()
157 .all(|c| c.is_alphanumeric() || c == '_' || c == '-')
158 {
159 return Err(SerializationError::ValidationFailed {
160 field: "username".to_string(),
161 message:
162 "Username can only contain alphanumeric characters, underscores, and hyphens"
163 .to_string(),
164 });
165 }
166
167 // Validate email (basic check)
168 if !email.contains('@') || !email.contains('.') || email.len() < 5 {
169 return Err(SerializationError::ValidationFailed {
170 field: "email".to_string(),
171 message: "Invalid email format".to_string(),
172 });
173 }
174
175 // Validate age
176 if !(13..=120).contains(&age) {
177 return Err(SerializationError::ValidationFailed {
178 field: "age".to_string(),
179 message: "Age must be between 13 and 120".to_string(),
180 });
181 }
182
183 // Validate preferences
184 if preferences.len() > 20 {
185 return Err(SerializationError::ValidationFailed {
186 field: "preferences".to_string(),
187 message: "Too many preferences (maximum 20)".to_string(),
188 });
189 }
190
191 for (key, value) in &preferences {
192 if key.len() > 50 || value.len() > 200 {
193 return Err(SerializationError::ValidationFailed {
194 field: "preferences".to_string(),
195 message: format!("Preference key/value too long: {}", key),
196 });
197 }
198 }
199
200 Ok(ValidatedUserInput {
201 username,
202 email,
203 age,
204 preferences,
205 })
206 }
207}
208
209impl ToFieldValue for ValidatedUserInput {
210 fn to_field_value(&self) -> FieldValue {
211 match self.to_json() {
212 Ok(json_str) => FieldValue::from_json_object(json_str),
213 Err(_) => FieldValue::from_string("serialization_error".to_string()),
214 }
215 }
216}
217
218impl FromFieldValue for ValidatedUserInput {
219 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
220 // Try JSON object first
221 if let Ok(json_data) = value.as_json_object() {
222 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
223 field: field_name.to_string(),
224 message: format!("Failed to deserialize ValidatedUserInput from JSON: {}", e),
225 });
226 }
227
228 // Try binary object
229 if let Ok(binary_data) = value.as_binary_object() {
230 return Self::from_binary(binary_data).map_err(|e| {
231 SerializationError::ValidationFailed {
232 field: field_name.to_string(),
233 message: format!(
234 "Failed to deserialize ValidatedUserInput from binary: {}",
235 e
236 ),
237 }
238 });
239 }
240
241 Err(SerializationError::ValidationFailed {
242 field: field_name.to_string(),
243 message: format!(
244 "Expected JsonObject or BinaryObject for ValidatedUserInput, found {}",
245 value.type_name()
246 ),
247 })
248 }
249}
250
251/// Recovery helper for handling partial data
252#[derive(Debug, Clone, PartialEq)]
253pub struct RecoverableData {
254 pub critical_field: String,
255 pub important_field: Option<String>,
256 pub optional_field: Option<String>,
257 pub metadata: HashMap<String, String>,
258}
259
260impl StructSerializable for RecoverableData {
261 fn to_serializer(&self) -> StructSerializer {
262 StructSerializer::new()
263 .field("critical_field", &self.critical_field)
264 .field("important_field", &self.important_field)
265 .field("optional_field", &self.optional_field)
266 .field("metadata", &self.metadata)
267 }
268
269 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
270 // Critical field - must exist
271 let critical_field = deserializer.field("critical_field")?;
272
273 // Important field - try to recover if missing
274 let important_field = deserializer.field_optional("important_field")?;
275
276 // Optional field - graceful fallback
277 let optional_field = deserializer.field_optional("optional_field")?;
278
279 // Metadata - recover what we can
280 let metadata = deserializer.field_or("metadata", HashMap::new())?;
281
282 Ok(RecoverableData {
283 critical_field,
284 important_field,
285 optional_field,
286 metadata,
287 })
288 }Sourcepub fn field_or<T: FromFieldValue>(
&mut self,
name: &str,
default: T,
) -> SerializationResult<T>
pub fn field_or<T: FromFieldValue>( &mut self, name: &str, default: T, ) -> SerializationResult<T>
Extract a field value with type conversion and provide a default if missing
Extracts a field from the deserializer and converts it to the specified type. If the field is missing, returns the provided default value instead of returning an error.
§Arguments
name- Name of the field to extractdefault- Default value to return if the field is missing
§Returns
The converted field value, or the default value if the field is missing. Returns an error only if the field exists but cannot be converted to the target type.
§Errors
Returns an error if:
- The field exists but cannot be converted to the target type
- Type conversion fails due to incompatible data
§Performance
Field extraction is O(1) average case. The field is removed from the deserializer if it exists.
Examples found in repository?
269 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
270 // Critical field - must exist
271 let critical_field = deserializer.field("critical_field")?;
272
273 // Important field - try to recover if missing
274 let important_field = deserializer.field_optional("important_field")?;
275
276 // Optional field - graceful fallback
277 let optional_field = deserializer.field_optional("optional_field")?;
278
279 // Metadata - recover what we can
280 let metadata = deserializer.field_or("metadata", HashMap::new())?;
281
282 Ok(RecoverableData {
283 critical_field,
284 important_field,
285 optional_field,
286 metadata,
287 })
288 }Sourcepub fn field_optional<T: FromFieldValue>(
&mut self,
name: &str,
) -> SerializationResult<Option<T>>
pub fn field_optional<T: FromFieldValue>( &mut self, name: &str, ) -> SerializationResult<Option<T>>
Extract a field value as an optional type
Extracts a field from the deserializer and converts it to the specified type,
returning Some(value) if the field exists and can be converted, or None
if the field is missing.
§Arguments
name- Name of the field to extract
§Returns
Some(converted_value) if the field exists and can be converted,
None if the field is missing, or an error if the field exists but
cannot be converted to the target type
§Errors
Returns an error if:
- The field exists but cannot be converted to the target type
- Type conversion fails due to incompatible data
§Performance
Field extraction is O(1) average case. The field is removed from the deserializer if it exists.
Examples found in repository?
57 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
58 let version = deserializer.field("version")?;
59 let name = deserializer.field("name")?;
60 let value = deserializer.field("value")?;
61
62 // Handle optional fields gracefully for schema evolution
63 let optional_field = deserializer.field_optional("optional_field")?;
64 let new_field = deserializer.field_optional("new_field")?;
65
66 // Validate version compatibility
67 if version > 3 {
68 return Err(SerializationError::ValidationFailed {
69 field: "version".to_string(),
70 message: format!("Unsupported version: {}. Maximum supported: 3", version),
71 });
72 }
73
74 Ok(VersionedData {
75 version,
76 name,
77 value,
78 optional_field,
79 new_field,
80 })
81 }
82}
83
84impl ToFieldValue for VersionedData {
85 fn to_field_value(&self) -> FieldValue {
86 match self.to_json() {
87 Ok(json_str) => FieldValue::from_json_object(json_str),
88 Err(_) => FieldValue::from_string("serialization_error".to_string()),
89 }
90 }
91}
92
93impl FromFieldValue for VersionedData {
94 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
95 // Try JSON object first
96 if let Ok(json_data) = value.as_json_object() {
97 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
98 field: field_name.to_string(),
99 message: format!("Failed to deserialize VersionedData from JSON: {}", e),
100 });
101 }
102
103 // Try binary object
104 if let Ok(binary_data) = value.as_binary_object() {
105 return Self::from_binary(binary_data).map_err(|e| {
106 SerializationError::ValidationFailed {
107 field: field_name.to_string(),
108 message: format!("Failed to deserialize VersionedData from binary: {}", e),
109 }
110 });
111 }
112
113 Err(SerializationError::ValidationFailed {
114 field: field_name.to_string(),
115 message: format!(
116 "Expected JsonObject or BinaryObject for VersionedData, found {}",
117 value.type_name()
118 ),
119 })
120 }
121}
122
123/// Validated user input with constraints
124#[derive(Debug, Clone, PartialEq)]
125pub struct ValidatedUserInput {
126 pub username: String,
127 pub email: String,
128 pub age: u16,
129 pub preferences: HashMap<String, String>,
130}
131
132impl StructSerializable for ValidatedUserInput {
133 fn to_serializer(&self) -> StructSerializer {
134 StructSerializer::new()
135 .field("username", &self.username)
136 .field("email", &self.email)
137 .field("age", &self.age)
138 .field("preferences", &self.preferences)
139 }
140
141 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
142 let username: String = deserializer.field("username")?;
143 let email: String = deserializer.field("email")?;
144 let age: u16 = deserializer.field("age")?;
145 let preferences: HashMap<String, String> = deserializer.field("preferences")?;
146
147 // Validate username
148 if username.is_empty() || username.len() > 50 {
149 return Err(SerializationError::ValidationFailed {
150 field: "username".to_string(),
151 message: "Username must be 1-50 characters long".to_string(),
152 });
153 }
154
155 if !username
156 .chars()
157 .all(|c| c.is_alphanumeric() || c == '_' || c == '-')
158 {
159 return Err(SerializationError::ValidationFailed {
160 field: "username".to_string(),
161 message:
162 "Username can only contain alphanumeric characters, underscores, and hyphens"
163 .to_string(),
164 });
165 }
166
167 // Validate email (basic check)
168 if !email.contains('@') || !email.contains('.') || email.len() < 5 {
169 return Err(SerializationError::ValidationFailed {
170 field: "email".to_string(),
171 message: "Invalid email format".to_string(),
172 });
173 }
174
175 // Validate age
176 if !(13..=120).contains(&age) {
177 return Err(SerializationError::ValidationFailed {
178 field: "age".to_string(),
179 message: "Age must be between 13 and 120".to_string(),
180 });
181 }
182
183 // Validate preferences
184 if preferences.len() > 20 {
185 return Err(SerializationError::ValidationFailed {
186 field: "preferences".to_string(),
187 message: "Too many preferences (maximum 20)".to_string(),
188 });
189 }
190
191 for (key, value) in &preferences {
192 if key.len() > 50 || value.len() > 200 {
193 return Err(SerializationError::ValidationFailed {
194 field: "preferences".to_string(),
195 message: format!("Preference key/value too long: {}", key),
196 });
197 }
198 }
199
200 Ok(ValidatedUserInput {
201 username,
202 email,
203 age,
204 preferences,
205 })
206 }
207}
208
209impl ToFieldValue for ValidatedUserInput {
210 fn to_field_value(&self) -> FieldValue {
211 match self.to_json() {
212 Ok(json_str) => FieldValue::from_json_object(json_str),
213 Err(_) => FieldValue::from_string("serialization_error".to_string()),
214 }
215 }
216}
217
218impl FromFieldValue for ValidatedUserInput {
219 fn from_field_value(value: FieldValue, field_name: &str) -> SerializationResult<Self> {
220 // Try JSON object first
221 if let Ok(json_data) = value.as_json_object() {
222 return Self::from_json(json_data).map_err(|e| SerializationError::ValidationFailed {
223 field: field_name.to_string(),
224 message: format!("Failed to deserialize ValidatedUserInput from JSON: {}", e),
225 });
226 }
227
228 // Try binary object
229 if let Ok(binary_data) = value.as_binary_object() {
230 return Self::from_binary(binary_data).map_err(|e| {
231 SerializationError::ValidationFailed {
232 field: field_name.to_string(),
233 message: format!(
234 "Failed to deserialize ValidatedUserInput from binary: {}",
235 e
236 ),
237 }
238 });
239 }
240
241 Err(SerializationError::ValidationFailed {
242 field: field_name.to_string(),
243 message: format!(
244 "Expected JsonObject or BinaryObject for ValidatedUserInput, found {}",
245 value.type_name()
246 ),
247 })
248 }
249}
250
251/// Recovery helper for handling partial data
252#[derive(Debug, Clone, PartialEq)]
253pub struct RecoverableData {
254 pub critical_field: String,
255 pub important_field: Option<String>,
256 pub optional_field: Option<String>,
257 pub metadata: HashMap<String, String>,
258}
259
260impl StructSerializable for RecoverableData {
261 fn to_serializer(&self) -> StructSerializer {
262 StructSerializer::new()
263 .field("critical_field", &self.critical_field)
264 .field("important_field", &self.important_field)
265 .field("optional_field", &self.optional_field)
266 .field("metadata", &self.metadata)
267 }
268
269 fn from_deserializer(deserializer: &mut StructDeserializer) -> SerializationResult<Self> {
270 // Critical field - must exist
271 let critical_field = deserializer.field("critical_field")?;
272
273 // Important field - try to recover if missing
274 let important_field = deserializer.field_optional("important_field")?;
275
276 // Optional field - graceful fallback
277 let optional_field = deserializer.field_optional("optional_field")?;
278
279 // Metadata - recover what we can
280 let metadata = deserializer.field_or("metadata", HashMap::new())?;
281
282 Ok(RecoverableData {
283 critical_field,
284 important_field,
285 optional_field,
286 metadata,
287 })
288 }Sourcepub fn field_with_error<T: FromFieldValue, F>(
&mut self,
name: &str,
error_fn: F,
) -> SerializationResult<T>
pub fn field_with_error<T: FromFieldValue, F>( &mut self, name: &str, error_fn: F, ) -> SerializationResult<T>
Extract a field value with custom error handling
Extracts a field from the deserializer and converts it to the specified type, using a custom error handling function to process any errors that occur during extraction or conversion.
§Arguments
name- Name of the field to extracterror_fn- Function to handle errors during field extraction or conversion
§Returns
The converted field value, or the result of the error handling function if an error occurs
§Errors
The error handling function can return any error type that implements the appropriate error traits. The function is called with the field name and the original error for context.
§Performance
Field extraction is O(1) average case. The error handling function is only called when an error occurs.
Sourcepub fn remaining_fields(&self) -> Vec<&str>
pub fn remaining_fields(&self) -> Vec<&str>
Get the names of all remaining fields
Returns a vector containing the names of all fields that have not yet been extracted from the deserializer. This is useful for debugging, validation, or implementing custom deserialization logic.
§Returns
A vector of field names that are still available for extraction
§Performance
This method performs O(n) work to collect all field names, where n is the number of remaining fields. The returned vector is a copy of the field names.
Sourcepub fn has_field(&self, name: &str) -> bool
pub fn has_field(&self, name: &str) -> bool
Check if a field exists
Returns whether a field with the specified name exists in the deserializer and has not yet been extracted. This is useful for conditional field extraction or validation.
§Arguments
name- Name of the field to check
§Returns
true if the field exists and has not been extracted, false otherwise
§Performance
This method performs O(1) average case lookup using HashMap contains_key.
Sourcepub fn from_json(json: &str) -> SerializationResult<Self>
pub fn from_json(json: &str) -> SerializationResult<Self>
Create a deserializer from a JSON string
Parses a JSON string and creates a StructDeserializer from its contents. The JSON string is expected to contain a valid JSON object that can be parsed into field-value pairs.
§Arguments
json- JSON string to parse
§Returns
A StructDeserializer containing the parsed field data, or an error if the JSON string cannot be parsed
§Errors
Returns an error if:
- The JSON string is malformed or invalid
- The JSON structure is not a valid object
- Parsing fails due to unexpected JSON format
§Performance
JSON parsing is performed in a single pass. The entire JSON string is processed to build the field map.
Sourcepub fn from_binary(data: &[u8]) -> SerializationResult<Self>
pub fn from_binary(data: &[u8]) -> SerializationResult<Self>
Create a deserializer from binary data
Parses binary data and creates a StructDeserializer from its contents. The binary data is expected to contain valid binary format data that was previously serialized using the binary format.
§Arguments
data- Binary data to parse
§Returns
A StructDeserializer containing the parsed field data, or an error if the binary data cannot be parsed
§Errors
Returns an error if:
- The binary data is malformed or corrupted
- The binary format is invalid or unsupported
- Parsing fails due to unexpected binary structure
- The data is truncated or incomplete
§Performance
Binary parsing is typically faster than JSON parsing due to the more compact format and lack of string parsing overhead.