I am trying to set up serde with my Request struct to turn it into JSON to pass it to an api:
#[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 = "http_serde::method")]
http_request_method: Option<http::Method>,
}
I would like to have some fields as optional in the sense that if they are None
then I just want to omit them from serialization. I am using serde_with
to skip None
fields, and it works for http_response_body: Option<bool>
but not for http_request_method: Option<http::Method>
. I am getting the following error:
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
What can I do to make this work?
You can wrap the crate's method::serialize
with your own function that takes &Option<Method>
.
fn method_opt<S: Serializer>(method_opt: &Option<Method>, ser: S) -> Result<S::Ok, S::Error> {
match method_opt {
Some(method) => http_serde::method::serialize(method, ser),
// This won't be encountered when using skip_serializing_none
None => panic!("This should only be used with `serde_with::skip_serializing_none`"),
}
}
Then use that for serializing.
#[serde(serialize_with = "method_opt")]
http_request_method: Option<http::Method>,
If you don't use skip_serializing_none
, you can change the None
branch to use ser.serialize_none()
, but this will only work with simple formats like JSON. Formats that have different handling of serialize_some
like RON will end up inconsistent.
If you want to create both serialization and deserialization for this struct, you can create two functions in a module as described in the serde documentation (example). This would have the same structure as the http_serde::method
module.