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

Rust中如何用serde_json将树形JSON配置解析为结构体?

Rust树形配置JSON解析方案

可以解析这类任意深度的树形JSON结构,但因为结构深度不固定,无法用固定层级的结构体实现,最简洁的方式是结合serde和serde_json库,用递归枚举定义节点类型。

步骤1:添加依赖

在Cargo.toml中引入所需库:

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

步骤2:定义递归枚举类型

用枚举区分非叶子节点(分支)和叶子节点(带val值),通过#[derive(Serialize, Deserialize)]自动实现JSON序列化/反序列化逻辑:

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

#[derive(Debug, Serialize, Deserialize)]
enum ConfigNode {
    // 非叶子节点:键到子节点的映射
    Branch(HashMap<String, ConfigNode>),
    // 叶子节点:存储val值(示例为整数,可根据实际类型调整)
    Leaf(i32),
}

步骤3:解析JSON示例

直接用serde_json::from_str将JSON字符串解析为ConfigNode:

fn main() -> Result<(), serde_json::Error> {
    let json_str = r#"{
        "a": {
            "d": { "val": 10 },
            "e": { "val": 20 }
        },
        "b": { "val": 5 },
        "c": { "val": 1 }
    }"#;

    // 解析JSON为ConfigNode
    let root: ConfigNode = serde_json::from_str(json_str)?;

    // 示例:递归遍历并打印所有叶子节点的val
    print_leaves(&root, "");
    Ok(())
}

fn print_leaves(node: &ConfigNode, path: &str) {
    match node {
        ConfigNode::Branch(children) => {
            for (key, child) in children {
                let new_path = if path.is_empty() {
                    key.clone()
                } else {
                    format!("{}.{}", path, key)
                };
                print_leaves(child, &new_path);
            }
        }
        ConfigNode::Leaf(val) => {
            println!("{}: {}", path, val);
        }
    }
}

补充说明

  • 如果val的类型不固定(比如字符串、布尔值等),可将Leaf的类型改为serde_json::Value,适配任意JSON值。
  • 递归枚举是处理任意深度树形结构的标准方案,serde会自动处理嵌套的反序列化逻辑,无需手动编写解析代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:45:19