Custom Serialization in Rust
Serialization is the process of converting data structures or objects into a format that can be stored or transmitted and later reconstructed. While Rust's serde crate provides powerful serialization capabilities, this challenge asks you to implement a custom serialization routine for a specific data structure, giving you a deeper understanding of the underlying principles. This exercise is valuable for understanding how data is represented and transformed, and for situations where you need fine-grained control over the serialization process.
Problem Description
You are tasked with creating a custom serialization function for a simple data structure called Record. A Record contains a unique identifier (id: u32), a name (name: String), and a list of integer values (values: Vec<i32>). Your serialization function should convert a Record into a string representation using a specific format:
The serialized string should be formatted as follows:
id,name,value1,value2,value3,...
Where:
idis the record's ID, converted to a string.nameis the record's name.valuesare the integer values in thevaluesvector, each converted to a string and separated by commas.
Your function should take a Record as input and return a String representing the serialized data.
Key Requirements:
- Handle empty
valuesvectors gracefully (no trailing comma). - Ensure proper comma separation between fields.
- The output string should not contain any leading or trailing spaces.
- The
idandvaluesshould be converted to strings.
Expected Behavior:
The function should correctly serialize Record instances into the specified string format.
Edge Cases to Consider:
- Empty
valuesvector. - Empty
namestring. - Large
valuesvector (consider performance, though this is not a primary focus). - Invalid input (though the input is guaranteed to be a valid
Record, consider how your code would handle potential errors if it weren't).
Examples
Example 1:
Input: Record { id: 123, name: "Alice".to_string(), values: vec![1, 2, 3] }
Output: "123,Alice,1,2,3"
Explanation: The ID (123) is converted to a string, the name ("Alice") is used as is, and the values [1, 2, 3] are converted to strings and joined with commas.
Example 2:
Input: Record { id: 456, name: "".to_string(), values: vec![] }
Output: "456,"
Explanation: The ID (456) is converted to a string, the name is an empty string, and the `values` vector is empty, resulting in a trailing comma.
Example 3:
Input: Record { id: 789, name: "Bob".to_string(), values: vec![10, -5, 0, 25] }
Output: "789,Bob,10,-5,0,25"
Explanation: Demonstrates handling of negative and zero values within the `values` vector.
Constraints
- The
idfield is always a positiveu32. - The
namefield is aString. - The
valuesfield is aVec<i32>. - The serialized string should not exceed 1024 characters. (This is a soft constraint; exceeding it shouldn't cause a crash, but it's good to be mindful of).
- Performance is not a primary concern, but avoid unnecessarily inefficient operations.
Notes
- You can use Rust's standard library functions for string manipulation and conversion.
- Consider using
joinfrom theitertoolscrate for efficiently concatenating thevaluesinto a comma-separated string (though it's not strictly required). - Think about how to handle the trailing comma correctly when the
valuesvector is empty. - Focus on clarity and correctness over extreme optimization.
#[derive(Debug)]
struct Record {
id: u32,
name: String,
values: Vec<i32>,
}
fn serialize_record(record: &Record) -> String {
let mut result = record.id.to_string();
result.push_str(",");
result.push_str(&record.name);
if !record.values.is_empty() {
let values_str: Vec<String> = record.values.iter().map(|&v| v.to_string()).collect();
result.push_str(",");
result.push_str(&values_str.join(","));
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_record_with_values() {
let record = Record {
id: 123,
name: "Alice".to_string(),
values: vec![1, 2, 3],
};
assert_eq!(serialize_record(&record), "123,Alice,1,2,3");
}
#[test]
fn test_serialize_record_with_empty_values() {
let record = Record {
id: 456,
name: "".to_string(),
values: vec![],
};
assert_eq!(serialize_record(&record), "456,");
}
#[test]
fn test_serialize_record_with_negative_values() {
let record = Record {
id: 789,
name: "Bob".to_string(),
values: vec![10, -5, 0, 25],
};
assert_eq!(serialize_record(&record), "789,Bob,10,-5,0,25");
}
}