如何使用Serde序列化Option<http::Method>并忽略None值?
解决Serde序列化Optionhttp::Method时的类型不匹配问题
问题场景
在配置Serde序列化Request结构体以调用API时,使用serde_with::skip_serializing_none让值为None的字段不参与序列化。其中http_response_body: Option<bool>可以正常工作,但http_request_method: Option<http::Method>出现类型不匹配错误:
error[E0308]: mismatched types --> src\zyte.rs:7:10 | 7 | #[derive(Serialize, Debug, Default)] | ^^^^^^^^^ | | | expected struct `Method`, found enum `Option` | arguments to this function are incorrect | = note: expected reference `&Method` found reference `&'__a std::option::Option<Method>` note: function defined here --> C:\Users\isaac\.cargo\registry\src\github.com-1ecc6299db9ec823\http-serde-1.1.2\src\lib.rs:237:12 | 237 | pub fn serialize<S: Serializer>(method: &Method, ser: S) -> Result<S::Ok, S::Error> { | ^^^^^^^^^ = note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info) For more information about this error, try `rustc --explain E0308`. error: could not compile `rust-simple-scraper` due to previous error
错误原因
http_serde::method提供的序列化函数仅接受&Method类型的参数,但我们的字段是Option<Method>。当直接用#[serde(with = "http_serde::method")]修饰Option类型字段时,Serde会将整个Option<Method>实例传递给该序列化函数,导致类型不匹配。而Option<bool>能正常工作是因为Serde默认支持基础类型的Option序列化逻辑。
解决方案
使用serde_with::OptionWrap来包装http_serde::method的序列化器,让它能处理Option<Method>类型:
首先导入OptionWrap:
use serde_with::OptionWrap;
然后修改结构体字段的Serde属性:
#[serde_with::skip_serializing_none] #[derive(Serialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub struct Request { #[serde(with = "http_serde::uri")] url: http::Uri, http_response_body: Option<bool>, #[serde(with = "serde_with::OptionWrap<http_serde::method>")] http_request_method: Option<http::Method>, }
原理说明
OptionWrap会先处理Option的逻辑:如果字段值是None,则结合skip_serializing_none跳过序列化;如果是Some(Method),则调用内部的http_serde::method序列化器来处理Method实例,完美适配类型要求。
内容的提问来源于stack exchange,提问作者Milo
相关产品推荐
相关产品推荐

