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.
Summary
derive_to_asyncapi_messageinjects 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:
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
typeconst 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
allOfof the$refplus the tag property, or by inlining), rather than emitting a bare$ref.Notes
Found while reviewing #17, where
examples/message_integration.rswas 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.