serde-rs / serde

Serialization framework for Rust
https://serde.rs/
Apache License 2.0
8.82k stars 748 forks source link

Externally tagged enum variants where all fields have `#[serde(default)]` should allow being written as a unit variant. #2691

Open Scripter17 opened 5 months ago

Scripter17 commented 5 months ago

I'm building a program that takes URLs and strips all the tracking parameters and handles redirects and so on. One of the mappers is ExpandShortLink, which just sends a request to the URL being cleaned and returns the URL the server responded with.

I'm trying to support the case where a user wants to specify HTTP headers for a specific ExpandShortLink without requiring that all uses of ExpandShortLink have a default header map (I expect it to be a niche feature).

Basically, I have this code:

use serde::Deserialize;
use serde_json::from_str;
use std::collections::HashMap;

#[derive(Deserialize)]
struct Rule {
    // ...
    mapper: Mapper
}

#[derive(Deserialize)]
enum Mapper {
    // ...
    ExpandShortLink {
        #[serde(default)]
        headers: HashMap<String, String>
    }
}

fn main() {
    assert!(from_str::<Rule>("{\"mapper\": {\"ExpandShortLink\": {\"headers\": {}}}}").is_ok());
    assert!(from_str::<Rule>("{\"mapper\": \"ExpandShortLink\"}").is_ok());
}

I would like to have {"mapper": "ExpandShortLink"} and {"mapper": {"ExpandShortLink": {"headers": {}}}} both deserialize to Rule {mapper: Mapper::ExpandShortLink {headers: HashMap::new()}}.

Scripter17 commented 4 months ago

Great so if I go to a different issue on github mobile and close it it has a chance of closing a random issue

Got it

Great

iTitus commented 2 months ago

Related to #2233 #2508 #2706 Will this get fixed by #2509 or #2520? #2295 also looks promising.

Scripter17 commented 2 months ago

The first and third PRs would definitely fix this. I'm not quite awake enough to make heads or tails of the second one but it seems to also handle this.