如何在Serde反序列化空数组时触发错误?
可行方案
针对你需要在反序列化空数组时触发错误的需求,以下是几种可行的实现方案:
方案1:自定义反序列化逻辑(无需额外依赖)
这种方式不需要引入第三方库,通过手动实现Serde的Deserialize trait添加空数组校验逻辑,有两种具体实现方式:
方式A:包装非空数组类型(复用性高)
如果项目中有多个地方需要验证非空数组,推荐定义一个通用的包装类型,避免重复代码:
use serde::{Deserialize, Deserializer}; // 定义包装非空数组的结构体 #[derive(Debug, Deserialize)] struct NonEmptyVec<T>(Vec<T>); // 为包装类型实现自定义反序列化 impl<T> Deserialize for NonEmptyVec<T> where T: Deserialize<'de>, { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { // 先完成基础的数组反序列化 let vec = Vec::deserialize(deserializer)?; // 校验数组是否为空,为空则返回自定义错误 if vec.is_empty() { return Err(serde::de::Error::custom("数组不能为空")); } Ok(NonEmptyVec(vec)) } } // 修改原结构体,使用包装类型替代普通Vec #[derive(Debug, Deserialize)] struct Doc { nums: NonEmptyVec<i32>, } fn main() { // 测试空数组场景:会触发反序列化错误 let empty_data = r#"{"nums": []}"#; match serde_json::from_str::<Doc>(empty_data) { Ok(doc) => dbg!(doc), Err(e) => eprintln!("反序列化失败: {}", e), } // 测试非空数组场景:正常解析 let valid_data = r#"{"nums": [1, 2, 3]}"#; let valid_doc = serde_json::from_str::<Doc>(valid_data).unwrap(); dbg!(valid_doc); }
方式B:直接为目标结构体实现反序列化
如果只是针对Doc结构体的nums字段做校验,可以直接为Doc实现Deserialize,省去包装类型:
use serde::{Deserialize, Deserializer}; #[derive(Debug)] struct Doc { nums: Vec<i32>, } // 为Doc实现自定义反序列化逻辑 impl<'de> Deserialize<'de> for Doc { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>, { // 定义临时结构体用于完成基础反序列化 #[derive(Deserialize)] struct TempDoc { nums: Vec<i32>, } let temp = TempDoc::deserialize(deserializer)?; // 校验nums数组是否为空 if temp.nums.is_empty() { return Err(serde::de::Error::custom("nums数组不能为空")); } Ok(Doc { nums: temp.nums }) } } fn main() { let empty_data = r#"{"nums": []}"#; match serde_json::from_str::<Doc>(empty_data) { Ok(doc) => dbg!(doc), Err(e) => eprintln!("反序列化失败: {}", e), } }
方案2:使用serde_with库简化校验
如果项目中已经引入serde_with库,可以用它提供的现成工具快速实现非空数组校验,减少手写代码量:
首先在Cargo.toml中添加依赖:
serde_with = "3.4"
然后编写代码:
use serde::Deserialize; use serde_with::{serde_as, non_empty_vec}; #[serde_as] #[derive(Debug, Deserialize)] struct Doc { // 用serde_with的non_empty_vec反序列化函数校验数组非空 #[serde(deserialize_with = "non_empty_vec")] nums: Vec<i32>, } fn main() { let empty_data = r#"{"nums": []}"#; match serde_json::from_str::<Doc>(empty_data) { Ok(doc) => dbg!(doc), Err(e) => eprintln!("反序列化失败: {}", e), } }
当nums为空数组时,反序列化会返回包含"Expected non-empty Vec"的错误信息,无需手动编写校验逻辑。
内容的提问来源于stack exchange,提问作者Blank
相关产品推荐
相关产品推荐

