Skip to content

refactor!: model MQTT scalar-or-schema values as a type hierarchy - #50

Open
bielu wants to merge 2 commits into
ByteBardOrg:vnextfrom
bielu:fix/mqtt-int-accessors-obsolete
Open

bielu wants to merge 2 commits into
ByteBardOrg:vnextfrom
bielu:fix/mqtt-int-accessors-obsolete

Conversation

@bielu

@bielu bielu commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Since #45, these MQTT fields can be an integer/string or a schema, but each was exposed twice: a union object with nullable Integer/LongInteger/Schema members, plus a scalar accessor kept for backward compatibility:

Property Union property
MQTTServerBinding.SessionExpiryInterval (int?) SessionExpiryIntervalValue
MQTTServerBinding.MaximumPacketSize (int?) MaximumPacketSizeValue
MQTTOperationBinding.MessageExpiryInterval (int?) MessageExpiryIntervalValue
MQTTMessageBinding.ResponseTopic (string) ResponseTopicValue

The int? accessors returned null for schema values and for values above Int32.MaxValue. MQTT allows up to 4294967295, and a 0xFFFFFFFF session expiry means "never expires", so it couldn't be told apart from "not set". Consumers also had to null-check members of the union to find out which alternative was present.

Change

Following review feedback, the unions are now a type hierarchy (same approach as AsyncApiAvroSchema):

  • MQTTIntegerOrSchema (abstract) → MQTTInteger (long Value) | MQTTIntegerSchema (AsyncApiJsonSchema Schema)
  • MQTTStringOrSchema (abstract) → MQTTString (string Value) | MQTTStringSchema (AsyncApiJsonSchema Schema)
  • Implicit conversions from long/string/AsyncApiJsonSchema to the base, and from each subtype back to its underlying value.
  • The scalar accessors and the *Value properties are removed. The four properties above now expose the union type directly, as MQTT5ServerBinding.SessionExpiryInterval already did.
binding.SessionExpiryInterval = 4294967295;              // MQTTInteger
binding.MaximumPacketSize = new AsyncApiJsonSchema { … }; // MQTTIntegerSchema

if (binding.SessionExpiryInterval is MQTTInteger interval) { long seconds = interval; }

Breaking change

v3.0.1 shipped these four properties as int?/string. Assignments still compile through the implicit conversions. Code that reads them as int?/string has to switch to type checks. The FromInteger/FromLong/FromSchema/FromString factories and the Integer/LongInteger members (unreleased, from #45) are replaced by the subtype constructors.

The full suite passes on net8.0/net9.0/net10.0.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 17 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7547badc-c2a2-4ea1-b22e-38140ad8ab66
📥 Commits

Reviewing files that changed from the base of the PR and between 70e73db and ccdb44e.

📒 Files selected for processing: 6
  • src/ByteBard.AsyncAPI.Bindings/MQTT/MQTTMessageBinding.cs
  • src/ByteBard.AsyncAPI.Bindings/MQTT/MQTTOperationBinding.cs
  • src/ByteBard.AsyncAPI.Bindings/MQTT/MQTTServerBinding.cs
  • src/ByteBard.AsyncAPI.Bindings/MQTT/MQTTValueUnions.cs
  • test/ByteBard.AsyncAPI.Tests/Bindings/MQTT/MQTTBindingVariants_Should.cs
  • test/ByteBard.AsyncAPI.Tests/Bindings/MQTT5/MQTT5Bindings_Should.cs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bielu
bielu marked this pull request as ready for review October 17, 2026 17:45
@bielu
bielu requested a review from VisualBean as a code owner October 17, 2026 17:45

@VisualBean VisualBean left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've never been a fan of these 'scalar or object' types.
Honestly this should be changed to a null object type thing and be given a hierachy.
New type, 2 subtype with implicit converters to their actual type. So consumer can use regular type checks rather than null validation.

I did something similar in other places.

Edit: they already have these types.. why the hell do they have the integers as well.

I'll dig further into the code

@bielu bielu changed the title fix: mark MQTT int accessors that hide large and schema values as obsolete refactor!: model MQTT scalar-or-schema values as a type hierarchy Oct 17, 2026
@VisualBean

Copy link
Copy Markdown
Contributor

God I love Claude sometimes

bielu and others added 2 commits October 17, 2026 19:14
…olete

MQTTServerBinding.SessionExpiryInterval, MaximumPacketSize and
MQTTOperationBinding.MessageExpiryInterval are int? views over the
MQTTIntegerOrSchema values. They return null when the value is a schema
or above Int32.MaxValue, which MQTT allows (up to 4294967295; for the
session expiry interval 0xFFFFFFFF means "never expires"). Callers
cannot tell that apart from "not set".

Keep the properties for compatibility, but document the behaviour and
mark them [Obsolete] pointing to the *Value properties. Tests now use
the *Value properties.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MQTTIntegerOrSchema and MQTTStringOrSchema are now abstract bases with
MQTTInteger/MQTTIntegerSchema and MQTTString/MQTTStringSchema subtypes,
so callers use type checks instead of null checks. Implicit conversions
from long/string/AsyncApiJsonSchema keep assignments such as
SessionExpiryInterval = 600 compiling, and each subtype converts back to
its underlying value.

The lossy int?/string accessors and the *Value properties are removed;
SessionExpiryInterval, MaximumPacketSize, MessageExpiryInterval and
ResponseTopic now expose the union type directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bielu
bielu force-pushed the fix/mqtt-int-accessors-obsolete branch from 617306c to ccdb44e Compare October 17, 2026 18:14
@bielu

bielu commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor Author

@VisualBean i have love/hate relation with claude, as it makes me faster in delivery of packages, but cognitive load is much higher 🙄

@VisualBean

Copy link
Copy Markdown
Contributor

@VisualBean i have love/hate relation with claude, as it makes me faster in delivery of packages, but cognitive load is much higher 🙄

And thank god for that. Only means you still care for the result.

It makes a lot of things faster, but also makes mistakes like a junior 😅 its all trade-offs 😁.
But for something pre-defined like this type-hierachy its almost a one-shot prompt to greatness

@bielu

bielu commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

@VisualBean yeah my approach is to treat it as working with junior developer 😂

@VisualBean

Copy link
Copy Markdown
Contributor

@VisualBean yeah my approach is to treat it as working with junior developer 😂

100% same for me. Extreme programming style + a lot of swearing 😂.

This branch has not been deployed

No deployments
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

Successfully merging this pull request may close these issues.

2 participants