Hone logo
Hone
Problems

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:

  • id is the record's ID, converted to a string.
  • name is the record's name.
  • values are the integer values in the values vector, 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 values vectors gracefully (no trailing comma).
  • Ensure proper comma separation between fields.
  • The output string should not contain any leading or trailing spaces.
  • The id and values should be converted to strings.

Expected Behavior:

The function should correctly serialize Record instances into the specified string format.

Edge Cases to Consider:

  • Empty values vector.
  • Empty name string.
  • Large values vector (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 id field is always a positive u32.
  • The name field is a String.
  • The values field is a Vec<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 join from the itertools crate for efficiently concatenating the values into a comma-separated string (though it's not strictly required).
  • Think about how to handle the trailing comma correctly when the values vector 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");
    }
}
Loading editor...
rust