You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Serde将含空对象值的JSON映射反序列化为字符串向量并实现反向序列化?

To solve this problem, we need to create a custom serialization/deserialization logic using Serde to convert between a JSON object with empty object values and a Vec<String> in Rust, while maintaining round-trip compatibility. Here's a step-by-step implementation:


Step 1: Add Dependencies

First, ensure your Cargo.toml includes the required Serde crates:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

Step 2: Define the Struct with Custom Serde Logic

We'll use Serde's serialize_with and deserialize_with attributes to hook into the conversion process for the my_list field. We also keep skip_serializing_if to omit the field when it's None.

use serde::{Deserialize, Serialize};
use std::collections::HashMap;

pub struct MyStruct {
    #[serde(
        skip_serializing_if = "Option::is_none",
        serialize_with = "serialize_my_list",
        deserialize_with = "deserialize_my_list"
    )]
    pub my_list: Option<Vec<String>>,
}

Step 3: Implement Custom Serialization

This function converts a Vec<String> back into a JSON object where each string becomes a key with an empty object as its value:

fn serialize_my_list<S>(value: &Option<Vec<String>>, serializer: S) -> Result<S::Ok, S::Error>
where
    S: serde::Serializer,
{
    match value {
        None => serializer.serialize_none(),
        Some(list) => {
            let mut map = serializer.serialize_map(Some(list.len()))?;
            for key in list {
                // Serialize each key with an empty object as its value
                map.serialize_entry(key, &serde_json::json!({}))?;
            }
            map.end()
        }
    }
}

Step 4: Implement Custom Deserialization

This function reads a JSON object, validates that all values are empty objects, and collects the keys into a Vec<String>:

fn deserialize_my_list<'de, D>(deserializer: D) -> Result<Option<Vec<String>>, D::Error>
where
    D: serde::Deserializer<'de>,
{
    // Handle cases where the field is missing or null
    let opt_map: Option<HashMap<String, serde_json::Value>> = Deserialize::deserialize(deserializer)?;

    match opt_map {
        None => Ok(None),
        Some(map) => {
            let mut list = Vec::new();
            for (key, value) in map {
                // Validate each value is an empty object
                match value {
                    serde_json::Value::Object(obj) if obj.is_empty() => list.push(key),
                    _ => return Err(serde::de::Error::custom(format!(
                        "Value for key '{}' must be an empty object", key
                    ))),
                }
            }
            Ok(Some(list))
        }
    }
}

Step 5: Test the Implementation

Verify the round-trip conversion works as expected:

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Test deserialization from sample JSON
    let json_input = r#"{"mylist": {"foo": {}, "bar": {}}}"#;
    let my_struct: MyStruct = serde_json::from_str(json_input)?;
    assert_eq!(my_struct.my_list, Some(vec!["foo".to_string(), "bar".to_string()]));

    // Test serialization back to JSON
    let json_output = serde_json::to_string_pretty(&my_struct)?;
    println!("Serialized JSON:\n{}", json_output);

    // Ensure round-trip consistency
    let round_trip: MyStruct = serde_json::from_str(&json_output)?;
    assert_eq!(round_trip.my_list, my_struct.my_list);

    Ok(())
}

Key Notes:

  • Validation: The deserialization step ensures all values in the JSON object are empty objects, which aligns with your original requirement. If you don't need this validation, you can simplify the code by collecting all keys directly.
  • Null/Missing Fields: The Option<Vec<String>> type handles cases where the mylist field is missing or set to null in the JSON, and skip_serializing_if ensures these cases aren't serialized back.

内容的提问来源于stack exchange,提问作者Semaphor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:27:41