Skip to content

fix(NATSRS-003): Info::cluster field uses skip_serializing_if but is Option<ClusterInfo>, missing Option::is_none guard - #47

Draft
flamingo[bot] wants to merge 1 commit into
mainfrom
ai-fix/natsrs-003-2-1bff4c8b
Draft

fix(NATSRS-003): Info::cluster field uses skip_serializing_if but is Option<ClusterInfo>, missing Option::is_none guard#47
flamingo[bot] wants to merge 1 commit into
mainfrom
ai-fix/natsrs-003-2-1bff4c8b

Conversation

@flamingo

@flamingo flamingo Bot commented Aug 11, 2026

Copy link
Copy Markdown

Closes findings from rule NATSRS-003 — Info::cluster field uses skip_serializing_if but is Option, missing Option::is_none guard.

Draft — this is a starting point, not a finished change. The fix required judgment, so read it before trusting it.

# Status Finding Location
1 ✅ fixed Info::cluster field uses skip_serializing_if but is Option, missing Option::is_none guard async-nats/src/jetstream/consumer/mod.rs:183
2 ✅ fixed pause_remaining uses serde_nanos but is Option, must use serde_nanos::option async-nats/src/jetstream/consumer/mod.rs:191
3 ✅ fixed pause_remaining Option field missing skip_serializing_if = "Option::is_none" async-nats/src/jetstream/consumer/mod.rs:191
4 ✅ fixed Info::paused field doc comment is placed after the cfg attribute, not before it async-nats/src/jetstream/consumer/mod.rs:187
5 ⚠️ not fixed FromConsumer::try_from_consumer_config returns crate::Error (Box) instead of a typed Error async-nats/src/jetstream/consumer/mod.rs:155

What changed — and what was deliberately left — is explained per finding as inline review comments on the lines each finding touched.


Run: https://product-hub.flamingo.so/admin/code-review
Run id: 1bff4c8b-6382-4a91-9010-0698bc64d01b

Merging this PR is recorded as acceptance of the rule that produced it;
closing it unmerged is recorded as rejection. Both feed rule health, so
closing a wrong suggestion is useful rather than merely tidy.

…Option<ClusterInfo>, missing Option::is_none guard

@flamingo flamingo Bot left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🦩 What this fix changed, finding by finding

5 finding(s) — 4 fixed (4 explained inline on the diff), 1 not fixed.

⚠️ Not fixed — needs human judgment

🔴 5. FromConsumer::try_from_consumer_config returns crate::Error (Box) instead of a typed Errorasync-nats/src/jetstream/consumer/mod.rs:155
NOT FIXED: The finding requests changing FromConsumer::try_from_consumer_config to return a typed Result<Self, ConsumerConversionError> with a new ConsumerConversionErrorKind enum and ConsumerConversionError type alias. This cannot be done mechanically in a single file without: (a) knowing whether ConsumerConversionError/ConsumerConversionErrorKind should live in this file or a shared error module, (b) updating all downstream implementations of FromConsumer in pull/mod.rs and push/mod.rs (which are separate files not provided), and (c) updating all call sites. Changing only this file would break the trait implementations in the other files and cause compilation errors. A real fix requires coordinated changes across at least pull/mod.rs, push/mod.rs, and this file, plus introducing the new error types.

🤖 Prompt for AI agents
In async-nats/src/jetstream/consumer/mod.rs around line 155, address this code-review finding: FromConsumer::try_from_consumer_config returns crate::Error (Box<dyn Error>) instead of a typed Error<Kind>.
The finding requests changing `FromConsumer::try_from_consumer_config` to return a typed `Result<Self, ConsumerConversionError>` with a new `ConsumerConversionErrorKind` enum and `ConsumerConversionError` type alias. This cannot be done mechanically in a single file without: (a) knowing whether `ConsumerConversionError`/`ConsumerConversionErrorKind` should live in this file or a shared error module, (b) updating all downstream implementations of `FromConsumer` in `pull/mod.rs` and `push/mod.rs` (which are separate files not provided), and (c) updating all call sites. Changing only this file would break the trait implementations in the other files and cause compilation errors. A real fix requires coordinated changes across at least `pull/mod.rs`, `push/mod.rs`, and this file, plus introducing the new error types.
Make the minimal change that resolves the finding; do not refactor unrelated code.

@@ -183,18 +183,18 @@ pub struct Info {
/// The number of messages pending delivery

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🦩 🟠 ✅ Fixed — Info::cluster field uses skip_serializing_if but is Option, missing Option::is_none guard

FIXED: Changed #[serde(skip_serializing_if = "is_default")] to #[serde(default, skip_serializing_if = "Option::is_none")] on the cluster field (was line 183). This correctly uses Option::is_none as the skip guard for the Option<ClusterInfo> field.

/// Indicates if any client is connected and receiving messages from a push consumer
#[serde(default, skip_serializing_if = "is_default")]
pub push_bound: bool,
#[cfg(feature = "server_2_11")]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🦩 🔴 ✅ Fixed — pause_remaining uses serde_nanos but is Option, must use serde_nanos::option

FIXED: Changed #[serde(default, with = "serde_nanos")] to #[serde(default, with = "serde_nanos::option", skip_serializing_if = "Option::is_none")] on the pause_remaining field (was line 191). This uses the correct serde_nanos::option adapter for Option<Duration> and adds the missing skip_serializing_if guard.

/// Indicates if any client is connected and receiving messages from a push consumer
#[serde(default, skip_serializing_if = "is_default")]
pub push_bound: bool,
#[cfg(feature = "server_2_11")]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🦩 🟠 ✅ Fixed — pause_remaining Option field missing skip_serializing_if = "Option::is_none"

FIXED: The skip_serializing_if = "Option::is_none" guard was added to pause_remaining as part of the same attribute change described in finding 2 above.

/// Information about the consumer's cluster
#[serde(skip_serializing_if = "is_default")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cluster: Option<ClusterInfo>,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

🦩 🔴 ✅ Fixed — Info::paused field doc comment is placed after the cfg attribute, not before it

FIXED: Moved the doc comment /// Indicates if the consumer is paused to before the #[cfg(feature = "server_2_11")] attribute on the paused field (was line 187). The doc comment now precedes all attributes, which is the correct Rust ordering.

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.

0 participants