Rust如何将JSON中字符串格式的数字反序列化到struct的u16字段
方案1:使用serde_with库(最简实现)
这是目前最推荐的方案,无需手写任何反序列化逻辑:
- 首先在
Cargo.toml中添加依赖:
serde_with = "3.4"
- 修改结构体定义:
use serde::Deserialize; use serde_with::serde_as; use std::time::Duration; use serde_humanize_rs; #[serde_as] #[derive(Deserialize, Debug, Clone)] #[serde(default)] struct FilterConfig { #[serde_as(as = "serde_with::DisplayFromStr")] ratelimit_limit: u16, #[serde_as(as = "serde_with::DisplayFromStr")] ratelimit_remaining: u16, #[serde(with = "serde_humanize_rs")] ratelimit_reset: Duration, }
DisplayFromStr会自动调用目标类型的FromStr实现完成字符串到数值的转换,所有原生数值类型都可以直接使用。
方案2:无额外依赖的通用实现
如果不想引入第三方库,可以写一个通用的反序列化函数复用:
use serde::{Deserialize, de::Deserializer}; fn deserialize_str_to_num<'de, T, D>(deserializer: D) -> Result<T, D::Error> where T: std::str::FromStr, T::Err: std::fmt::Display, D: Deserializer<'de>, { let s = String::deserialize(deserializer)?; s.parse().map_err(serde::de::Error::custom) }
在对应字段上指定该反序列化函数即可:
#[derive(Deserialize, Debug, Clone)] #[serde(default)] struct FilterConfig { #[serde(deserialize_with = "deserialize_str_to_num")] ratelimit_limit: u16, #[serde(deserialize_with = "deserialize_str_to_num")] ratelimit_remaining: u16, #[serde(with = "serde_humanize_rs")] ratelimit_reset: Duration, }
该函数支持所有实现了FromStr trait的类型,无需为不同数值类型单独实现反序列化器。
内容的提问来源于stack exchange,提问作者Lahiru Udayanga
相关产品推荐
相关产品推荐

