Skip to content

Newtype enum variants lose the serde tag discriminant in generated payload schemas #18

Description

@mlilback

Summary

derive_to_asyncapi_message injects the serde tag discriminant (e.g. "type": {"const": "user.join"}) into the payload schema for struct-like enum variants, but not for newtype variants. For an internally-tagged enum, serde does emit the tag on the wire in both cases, so the generated schema for a newtype variant doesn't match the actual message — a consumer validating against the published spec would reject valid messages.

Reproduction

Given an internally-tagged enum mixing variant shapes:

#[derive(Serialize, Deserialize, JsonSchema, ToAsyncApiMessage)]
#[serde(tag = "type")]
pub enum ChatMessage {
    #[asyncapi_message(name = "ChatMessage", title = "...")]
    Chat { text: String },

    #[asyncapi_message(name = "UserJoin", title = "...")]
    UserJoin(UserJoin),
}

The struct-like variant gets a payload schema carrying its const tag:

{ "properties": { "type": { "const": "chat" }, "text": { "type": "string" } } }

The newtype variant gets only:

{ "$ref": "#/components/schemas/UserJoin" }

with no type const property, even though serde serializes it as {"type":"user.join","username":...,"room":...}.

Expected

The tag should be injected for newtype variants too — presumably by merging the const property into the referenced schema (an allOf of the $ref plus the tag property, or by inlining), rather than emitting a bare $ref.

Notes

Found while reviewing #17, where examples/message_integration.rs was changed to use a newtype variant and the discriminant silently disappeared from the example's output. That example change is being reverted separately; this issue tracks the underlying codegen gap.

See #17 (review) for the original finding.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions