3
votes

I've read the docs, but I haven't seen a way to solve my problem. I'm parsing an API response which on success would return only a 2xx status code, while on bad requests it sends JSON.

extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

fn main() {
    let _: X = serde_json::from_str(r#"{ "ok": true }"#).expect("with string");
    let _: X = serde_json::from_str("").expect("empty string");
}

#[derive(Deserialize)]
struct X {
    ok: Option<bool>,
}

Playground

This is the struct I would like to deserialize into. I've tried adding #[serde(skip_serializing_if = "some_func")] to the field, but it doesn't change anything.

The error is

Error("EOF while parsing a value", line: 1, column: 0)

Is there a way to handle this properly, or do I always have to check the status code if it's 2xx before attempting to deserialize the response?

1
Can you provide your full attempt with #[serde(skip_serializing_if...)], including some_func? - E_net4
I've only attempted it with a simple func that just returned `true˙ to see if it works. Since it didn't (got the same error) I didn't really bother with it anymore. - Andrew
Oh! Well, for one, you probably meant to use #[serde(skip_deserializing)], not #[serde(skip_serializing)]. The latter only works when encoding the value. :) - E_net4
Moreover, consider making a full minimal reproducible example, by including a small main function deserializing an example of a response reproducing the issue. This makes the question much easier to address and much easier for us to help. - E_net4
Ahh, right, I've totally missed that. :) I thought I can't use external crates on play, my bad, I'll edit my post. - Andrew

1 Answers

1
votes

The main problem here is that the empty string is not valid JSON according to most parsers including the one built into ES6 and apparently Serde. There are three possible solutions that I see to this problem.

  • Return an empty dict from the endpoint
  • Do not blindly attempt deserialization of the empty string checking first for the content length of the response body.
  • Implement a custom Deserialize method