Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fields inside untagged enum #9

Closed
ctaggart opened this issue Sep 28, 2020 · 2 comments
Closed

Fields inside untagged enum #9

ctaggart opened this issue Sep 28, 2020 · 2 comments

Comments

@ctaggart
Copy link

-- ❤️ --> Serde is amazing! Thank you for making it.

I wrote an assert_deserialized_without_ignored, hoping that it would catch anything that is ignored, but it misses many items. Did I misunderstand something?

pub fn assert_deserialize_without_ignored<P: AsRef<Path> + std::fmt::Debug>(paths: Vec<P>) -> Result<()> {
    for path in paths {
        println!("  test {:?}", path);
        let mut bytes = Vec::new();
        File::open(path)?.read_to_end(&mut bytes)?;
        let deserializer = &mut serde_json::Deserializer::from_slice(&bytes);
        let mut ignored = Vec::new();
        let _spec: OpenAPI = serde_ignored::deserialize(deserializer, |path| {
            let path = path.to_string();
            println!("    ignored {}", &path);
            ignored.push(path);
        })?;
        assert_eq!(0, ignored.len());
    }
    Ok(())
}

See ctaggart/autorust_openapi#3 (comment) for a specific case about x-nullable not showing up as ignored for https://github.com/Azure/azure-rest-api-specs/blob/master/specification/batch/data-plane/Microsoft.Batch/stable/2020-09-01.12.0/BatchService.json.

@dtolnay
Copy link
Owner

dtolnay commented Sep 28, 2020

You have x-nullable inside something that is being deserialized as ReferenceOr. The untagged enum is equivalent to deserializing everything in the object to a format-independent variation of serde_json::Value and sequentially attempting to deserialize the Value to each possible untagged variant.

It looks like you are expecting to identify ReferenceOr::Reference based on presence of a $ref field. If $ref is guaranteed to be first field, you can write a Deserialize impl which looks for it as the first field to decide whether to deserialize as Reference or Item. If it is not guaranteed to be the first field, there is no way you can avoid deserializing previous fields while looking for $ref, including fields that you don't end up putting into ReferenceOr::Item after not finding a $ref.

@dtolnay dtolnay changed the title missing many ignored items Fields inside untagged enum Sep 28, 2020
@ctaggart
Copy link
Author

Thank you for digging into it and the explanation. 💟 You renamed this the issue title, so I assume you wish to keep it open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants