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

Union discriminator does not work with enums of vec #755

Open
dadepo opened this issue Feb 21, 2024 · 1 comment
Open

Union discriminator does not work with enums of vec #755

dadepo opened this issue Feb 21, 2024 · 1 comment

Comments

@dadepo
Copy link

dadepo commented Feb 21, 2024

Actual Behavior

Given this enum

#[derive(Union, Serialize)]
#[oai(discriminator_name = "type")]
pub enum EqExpr {
    #[serde(rename = "@eq")]
    #[oai(mapping = "@eq")]
    Eq(PathInfo),
    #[serde(rename = "@neq")]
    #[oai(mapping = "@neq")]
    NotEq(PathInfo)
}

Serialising with both serde and poem

        let value = EqExpr::Eq(PathInfo {
            path: "age".to_string(),
            value: json!(20),
        });
        // Serialise with serde
        dbg!(serde_json::to_string(&value).unwrap());
        // Prints: "{\"@eq\":{\"path\":\"age\",\"value\":20}}"
        
        // Serialise with poem
        dbg!(&value.to_json_string());
        // Prints "{\"path\":\"age\",\"type\":\"@eq\",\"value\":20}"

        let value = EqExpr::NotEq(PathInfo {
            path: "age".to_string(),
            value: json!(20),
        });
        // Serialise with serde
        dbg!(serde_json::to_string(&value).unwrap());
        // Prints "{\"@neq\":{\"path\":\"age\",\"value\":20}}"
        
        // Serialise with poem
        dbg!(&value.to_json_string());
        // Prints "{\"path\":\"age\",\"type\":\"@neq\",\"value\":20}"

This is good and dandy, poem does not support externally tagged enums, but the "type": "..." acts as the discriminator.

Now if the enum is changed to the following:

#[derive(Union, Serialize)]
#[oai(discriminator_name = "type")]
pub enum EqExpr {
    #[serde(rename = "@eq")]
    #[oai(mapping = "@eq")]
    Eq(Vec<PathInfo>),
    #[serde(rename = "@neq")]
    #[oai(mapping = "@neq")]
    NotEq(Vec<PathInfo>)
}

Then serialised like this

        let value = EqExpr::Eq(vec![PathInfo {
            path: "age".to_string(),
            value: json!(20),
        }]);
        // Serialise with serde
        dbg!(serde_json::to_string(&value).unwrap());
        // Serialise with poem
        dbg!(&value.to_json_string());

        let value = EqExpr::NotEq(vec![PathInfo {
            path: "age".to_string(),
            value: json!(20),
        }]);

        // Serialise with serde
        dbg!(serde_json::to_string(&value).unwrap());
        // Serialise with poem
        dbg!(&value.to_json_string());

it prints:

[crates/src/lib.rs:500] serde_json::to_string(&value).unwrap() = "{\"@eq\":[{\"path\":\"age\",\"value\":20}]}"
[crates/src/lib.rs:502] &value.to_json_string() = "[{\"path\":\"age\",\"value\":20}]"
[crates/src/lib.rs:510] serde_json::to_string(&value).unwrap() = "{\"@neq\":[{\"path\":\"age\",\"value\":20}]}"
[crates/src/lib.rs:512] &value.to_json_string() = "[{\"path\":\"age\",\"value\":20}]"

As can be seen, with serde the externally discrimination of the enums, makes it possible to differentiate between the two enums, but with poem, both prints [{\"path\":\"age\",\"value\":20}].

Expected Behavior

poem should not serialise both of the enum variants into the same json string representation.

Because of this, it is also impossible to deserialise into the rust enums.

Specifications

  • Version:

poem = { version = "2.0.0" }
poem-openapi = { version = "4.0.0", features = ["swagger-ui", "uuid"] }

  • Platform:

~ uname -a
Darwin DeeMBP2773 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000 arm64

@dadepo dadepo added the bug Something isn't working label Feb 21, 2024
@sunli829
Copy link
Collaborator

The members in the enumeration must be an Object, and I will update Union macro to recognize this error at compile time.

@sunli829 sunli829 removed the bug Something isn't working label Mar 24, 2024
sunli829 added a commit that referenced this issue Mar 24, 2024
…bject`, an error will be reported at compile time. #755
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