如何正确定义Rust Serde数据类型以实现JSON反序列化?
解决Serde反序列化Filter枚举的问题
你的错误data did not match any variant of untagged enum Filter源于枚举变体的结构未匹配JSON的单键对象格式。要同时支持逻辑运算符(and/or)和比较运算符(eq/gt/lt等),需让枚举每个变体严格对应JSON的单键结构:
1. 添加依赖
确保Cargo.toml中包含Serde相关依赖:
[dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0"
2. 正确定义Filter枚举
通过#[serde(untagged)]标记枚举,每个变体对应JSON中的单键对象结构:
use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Deserialize, Serialize)] #[serde(untagged)] enum Filter { // 逻辑运算符:对应 {"and": [Filter数组]} And { and: Vec<Filter> }, // 逻辑运算符:对应 {"or": [Filter数组]} Or { or: Vec<Filter> }, // 比较运算符:对应 {"eq": {字段: 值}} Eq { eq: HashMap<String, serde_json::Value> }, // 扩展其他比较运算符 Gt { gt: HashMap<String, serde_json::Value> }, Lt { lt: HashMap<String, serde_json::Value> }, Ge { ge: HashMap<String, serde_json::Value> }, Le { le: HashMap<String, serde_json::Value> }, Ne { ne: HashMap<String, serde_json::Value> }, }
3. 测试反序列化
以下代码可验证简单和复杂嵌套场景的反序列化:
fn main() -> Result<(), Box<dyn std::error::Error>> { // 简单比较场景 let simple_json = r#"{"eq": {"name": "Alice"}}"#; let simple_filter: Filter = serde_json::from_str(simple_json)?; println!("简单过滤器: {:?}", simple_filter); // 复杂逻辑嵌套场景 let complex_json = r#"{ "and": [ {"gt": {"age": 18}}, {"or": [ {"eq": {"active": true}}, {"ne": {"role": "guest"}} ]} ] }"#; let complex_filter: Filter = serde_json::from_str(complex_json)?; println!("复杂过滤器: {:?}", complex_filter); Ok(()) }
关键说明
#[serde(untagged)]让Serde自动匹配每个变体的结构,无需显式标记类型字段。- 逻辑运算符变体对应键为运算符名、值为Filter数组的对象;比较运算符变体对应键为运算符名、值为字段-值映射的对象,完全贴合JSON结构。
- 使用
serde_json::Value作为值类型,支持字符串、数字、布尔等多种数据类型,适配不同字段的比较需求。
内容的提问来源于stack exchange,提问作者Tin
相关产品推荐
相关产品推荐

