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
相关产品推荐
相关产品推荐

