Skip to content

Introduce PacketParts and optional correlation IDs#282

Merged
leynos merged 13 commits intomainfrom
etft5a-codex/address-code-review-comments
Aug 12, 2025
Merged

Introduce PacketParts and optional correlation IDs#282
leynos merged 13 commits intomainfrom
etft5a-codex/address-code-review-comments

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented Aug 8, 2025

Summary

  • replace raw correlation_id fields with Option<u64> and add PacketParts
  • flatten Envelope and propagate correlation IDs through middleware
  • log correlation_id alongside message IDs for easier debugging

Testing

  • make fmt
  • make lint
  • make test
  • make markdownlint

https://chatgpt.com/codex/tasks/task_e_68953cfe46648322978c741264be93a3

Summary by Sourcery

Introduce optional correlation identifiers and a unified PacketParts struct for packet APIs, flatten Envelope, propagate correlation IDs through middleware and routing logic, and enrich logging and tests to support optional correlation IDs

New Features:

  • Add PacketParts struct to encapsulate packet id, optional correlation_id, and payload

Enhancements:

  • Change Packet and Envelope APIs to use Option for correlation IDs
  • Flatten Envelope by removing PacketHeader and switch Packet trait to use PacketParts
  • Propagate optional correlation IDs through ServiceRequest, ServiceResponse, and route handling
  • Include correlation_id in tracing logs alongside message IDs for better debugging

Documentation:

  • Update README example to demonstrate PacketParts usage and optional correlation_id

Tests:

  • Update tests and examples to handle Option correlation IDs
  • Add middleware test to verify non-zero correlation IDs are preserved

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 8, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Warning

Rate limit exceeded

@leynos has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0cf6188 and c565a23.

📒 Files selected for processing (1)
  • docs/rust-binary-router-library-design.md (1 hunks)

Summary by CodeRabbit

  • New Features

    • Introduced a packet decomposition type to simplify building/parsing frames, with helpers for correlation inheritance and conversions.
    • Envelopes and request/response types now carry an optional correlation ID to support unsolicited events.
  • Refactor

    • Unified request/response flow on the new packet parts model; updated method signatures to align with optional correlation IDs.
  • Bug Fixes

    • Clearer runtime error messages replace generic panics in examples.
  • Documentation

    • Updated guides and API docs to cover the new packet model, optional correlation semantics, and roadmap progress.

Walkthrough

Convert correlation IDs from u64 to Option, introduce a public PacketParts type, and update the Packet trait, Envelope, middleware, examples, docs and tests to use PacketParts and optional correlation IDs (None denotes unsolicited/server-initiated frames).

Changes

Cohort / File(s) Change Summary
Core packet API & envelope
src/app.rs, docs/rust-binary-router-library-design.md, docs/api.md
Add public PacketParts { id: u32, correlation_id: Option<u64>, payload: Vec<u8> }; change Packet trait to correlation_id() -> Option<u64> and to use PacketParts for into_parts()/from_parts(); simplify Envelope to store id, correlation_id: Option<u64>, payload; add From<Envelope> for PacketParts and From<PacketParts> for Envelope; add PacketParts::inherit_correlation.
Middleware & service types
src/middleware.rs
Change ServiceRequest/ServiceResponse to carry Option<u64> correlation IDs; add constructors, accessors and setters; build envelopes via PacketParts and propagate correlation through routes; update RouteService to use PacketParts.
Examples & README
README.md, examples/metadata_routing.rs, examples/ping_pong.rs
Update examples to import/use PacketParts; construct Envelope::new(..., Option<u64>, ...); ensure error responses include correlation_id; replace several unwrap() calls with expect(...) messages.
Tests — packet implementations & unit tests
tests/routes.rs, tests/lifecycle.rs, tests/packet_parts.rs
Rename msgpayload, change correlation_id: u64Option<u64>, adapt Packet impls to return/consume PacketParts; add PacketParts unit tests for round-trip and inherit_correlation.
Tests — envelope creation & assertions
tests/correlation_id.rs, tests/metadata.rs, tests/middleware_order.rs, tests/world.rs
Replace numeric correlation args with Some(...)/None; update assertions to expect Option<u64>; switch response handling to use Packet::into_parts(...) and parts accessors.
Middleware behaviour & tests
tests/middleware.rs, tests/middleware_order.rs
Ensure middleware and routing preserve optional correlation IDs; add parameterised tests over None and Some(cid); add ServiceRequest::set_correlation_id and assert response.correlation_id() preserved.
Docs & roadmap
docs/roadmap.md, docs/api.md, docs/rust-binary-router-library-design.md
Document PacketParts, semantics of None as unsolicited/server push; update README examples and roadmap checklist for packet decomposition and optional correlation IDs.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Middleware
    participant Router
    participant Handler

    Client->>Middleware: Send Envelope(id, correlation_id: Option<u64>, payload)
    Middleware->>Router: Build ServiceRequest(frame, correlation_id)
    Router->>Handler: Route payload using PacketParts (id, correlation_id, payload)
    Handler-->>Router: Return ServiceResponse(payload, correlation_id)
    Router->>Middleware: Build Envelope from PacketParts (inherit correlation)
    Middleware->>Client: Send Envelope(id, correlation_id, payload)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Poem

Wrap IDs in Option light, PacketParts take the stage,
Envelopes grow leaner, traits now turn a page.
Thread the cid through middleware, route and test,
Run the suite, pass green, then merge with quiet zest.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch etft5a-codex/address-code-review-comments

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

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

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Aug 8, 2025

Reviewer's Guide

Refactors correlation ID handling to be optional and generic by introducing PacketParts, flattens Envelope, propagates IDs through middleware and handlers, enhances logging context, and updates related tests and examples for the new API.

Class diagram for Packet, PacketParts, and Envelope changes

classDiagram
    class Packet {
        +id() u32
        +correlation_id() Option<u64>
        +into_parts() PacketParts
        +from_parts(parts: PacketParts) Self
    }
    class PacketParts {
        +id: u32
        +correlation_id: Option<u64>
        +msg: Vec<u8>
    }
    class Envelope {
        +id: u32
        +correlation_id: Option<u64>
        +msg: Vec<u8>
        +new(id: u32, correlation_id: Option<u64>, msg: Vec<u8>)
        +into_parts() PacketParts
    }
    Packet <|.. Envelope
    PacketParts <.. Envelope : uses
    PacketParts <.. Packet : uses
Loading

Class diagram for ServiceRequest and ServiceResponse changes

classDiagram
    class ServiceRequest {
        -inner: FrameContainer<Vec<u8>>
        -correlation_id: Option<u64>
        +new(frame: Vec<u8>, correlation_id: Option<u64>)
        +frame() &[u8]
        +correlation_id() Option<u64>
        +frame_mut() &mut Vec<u8>
        +into_inner() Vec<u8>
    }
    class ServiceResponse {
        -inner: FrameContainer<Vec<u8>>
        -correlation_id: Option<u64>
        +new(frame: Vec<u8>, correlation_id: Option<u64>)
        +frame() &[u8]
        +frame_mut() &mut Vec<u8>
        +correlation_id() Option<u64>
        +into_inner() Vec<u8>
    }
    class FrameContainer~T~ {
        +new(frame: T)
        +frame() &T
        +frame_mut() &mut T
        +into_inner() T
    }
    ServiceRequest o-- FrameContainer
    ServiceResponse o-- FrameContainer
Loading

File-Level Changes

Change Details Files
Introduce PacketParts and update Packet trait to use PacketParts and Option
  • Add PacketParts struct with fields id, correlation_id: Option, and msg
  • Change Packet::correlation_id to return Option
  • Refactor Packet::into_parts and Packet::from_parts to use PacketParts
src/app.rs
README.md
Flatten Envelope by removing PacketHeader and embedding its fields
  • Remove PacketHeader type
  • Inline id and Option correlation_id directly in Envelope
  • Update Envelope::new and into_parts implementations
  • Adjust Packet impl for Envelope to match new structure
src/app.rs
Propagate optional correlation_id through ServiceRequest and ServiceResponse
  • Update ServiceRequest and ServiceResponse to store Option
  • Modify new, correlation_id accessors, and into_inner methods
  • Refactor RouteService call to build and deconstruct PacketParts
src/middleware.rs
Enhance logging to include correlation_id context
  • Include correlation_id in tracing::warn! calls for handler errors, no handler, and response send failures
  • Add id and correlation_id fields to log metadata
src/app.rs
Update tests, examples, and README for optional correlation_id and PacketParts usage
  • Change test and example envelopes to use Option for correlation_id
  • Update assertions to expect Some(value) and adjust frame deserializations
  • Add new middleware test to verify non-zero correlation ID preservation
  • Refactor examples and README to illustrate PacketParts patterns
tests/routes.rs
tests/lifecycle.rs
tests/world.rs
tests/correlation_id.rs
tests/middleware_order.rs
tests/metadata.rs
tests/middleware.rs
examples/ping_pong.rs
examples/metadata_routing.rs
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

sourcery-ai[bot]

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 8, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 11

🔭 Outside diff range comments (1)
src/middleware.rs (1)

47-52: Expose a way to set/overwrite correlation IDs in middleware

Enable middleware to attach or scrub correlation IDs by adding a setter on ServiceRequest.

Apply inside this impl:

impl ServiceRequest {
    // …

    /// Set or clear the correlation identifier.
    pub fn set_correlation_id(&mut self, correlation_id: Option<u64>) {
        self.correlation_id = correlation_id;
    }
}
♻️ Duplicate comments (7)
src/app.rs (5)

189-197: Add unit tests for Packet::from_parts and into_parts

Add tests that round-trip via PacketParts for:

  • correlation_id = None
  • correlation_id = Some(value)
  • empty payload vs non-empty payload

Prefer rstest with parameterised cases per guidelines.

I can draft rstest-based cases if helpful.


199-205: Introduce From/Into conversions between Envelope and PacketParts to remove boilerplate

Define canonical From conversions and switch Packet impl to them. This centralises mapping logic as previously suggested.

Apply this change:

+impl From<Envelope> for PacketParts {
+    fn from(e: Envelope) -> Self {
+        PacketParts { id: e.id, correlation_id: e.correlation_id, msg: e.msg }
+    }
+}
+
+impl From<PacketParts> for Envelope {
+    fn from(p: PacketParts) -> Self {
+        Envelope::new(p.id, p.correlation_id, p.msg)
+    }
+}

Then simplify the Packet impl (see comment at lines 241-249).


229-237: Prefer centralised conversion in into_parts

Route Envelope::into_parts via the new From impl to avoid duplication and keep a single source of truth.

Apply:

-    pub fn into_parts(self) -> PacketParts {
-        PacketParts {
-            id: self.id,
-            correlation_id: self.correlation_id,
-            msg: self.msg,
-        }
-    }
+    pub fn into_parts(self) -> PacketParts { self.into() }

241-249: Simplify Packet impl using the From/Into conversions

Stop re-stating field mappings; delegate to conversions.

Apply:

-    fn into_parts(self) -> PacketParts { Envelope::into_parts(self) }
+    fn into_parts(self) -> PacketParts { self.into() }

-    fn from_parts(parts: PacketParts) -> Self {
-        Envelope::new(parts.id, parts.correlation_id, parts.msg)
-    }
+    fn from_parts(parts: PacketParts) -> Self { parts.into() }

746-752: Log correlation_id mismatches explicitly

Detect and log mismatches between request and response correlation IDs. Deepwiki research confirms that optional correlation IDs propagate through PushHandle and WireframeProtocol; any divergence should surface in logs. Update the code in src/app.rs around line 750 as follows:

@@ src/app.rs:748-752
-                    let correlation_id = resp.correlation_id().or(env.correlation_id);
+                    let req_cid = env.correlation_id;
+                    let res_cid = resp.correlation_id();
+                    if let (Some(rq), Some(rs)) = (req_cid, res_cid) {
+                        if rq != rs {
+                            tracing::warn!(
+                                id = env.id,
+                                req_correlation_id = rq,
+                                res_correlation_id = rs,
+                                "correlation_id mismatch between request and response"
+                            );
+                        }
+                    }
+                    let correlation_id = res_cid.or(req_cid);

Confirmed no other .or(env.correlation_id) usages without mismatch checks.

tests/middleware_order.rs (1)

91-93: Assert correlation_id (and id) in response to validate propagation

Add assertions to verify the middleware preserves the correlation ID and message ID alongside the frame mutation.

-    let parts = resp.into_parts();
-    assert_eq!(parts.msg, vec![b'X', b'A', b'B', b'B', b'A']);
+    let parts = resp.into_parts();
+    assert_eq!(parts.correlation_id, Some(7));
+    assert_eq!(parts.id, 1);
+    assert_eq!(parts.msg, vec![b'X', b'A', b'B', b'B', b'A']);
src/middleware.rs (1)

314-323: Reduce boilerplate with PacketParts::new constructor

Replace the struct literal with a PacketParts::new(...) constructor to slim call-sites. This repeats prior feedback.

Use after adding the constructor:

-        let parts = PacketParts {
-            id: self.id,
-            correlation_id: req.correlation_id(),
-            msg: req.into_inner(),
-        };
-        let env = E::from_parts(parts);
+        let env = E::from_parts(PacketParts::new(
+            self.id,
+            req.correlation_id(),
+            req.into_inner(),
+        ));

Add in impl PacketParts (in the app module):

impl PacketParts {
    #[must_use]
    pub fn new(id: u32, correlation_id: Option<u64>, msg: Vec<u8>) -> Self {
        Self { id, correlation_id, msg }
    }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ce4bce5 and 36b86c1.

📒 Files selected for processing (12)
  • README.md (1 hunks)
  • examples/metadata_routing.rs (1 hunks)
  • examples/ping_pong.rs (1 hunks)
  • src/app.rs (4 hunks)
  • src/middleware.rs (6 hunks)
  • tests/correlation_id.rs (1 hunks)
  • tests/lifecycle.rs (3 hunks)
  • tests/metadata.rs (2 hunks)
  • tests/middleware.rs (2 hunks)
  • tests/middleware_order.rs (2 hunks)
  • tests/routes.rs (6 hunks)
  • tests/world.rs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • tests/correlation_id.rs
  • tests/middleware_order.rs
  • tests/metadata.rs
  • tests/world.rs
  • tests/middleware.rs
  • examples/metadata_routing.rs
  • examples/ping_pong.rs
  • tests/lifecycle.rs
  • src/middleware.rs
  • tests/routes.rs
  • src/app.rs
**/*.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Paragraphs and bullets must be wrapped to 80 columns, except where a long URL would prevent this (in which case, silence MD013 for that line)
  • Code blocks should be wrapped to 120 columns.
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • README.md
🧬 Code Graph Analysis (4)
tests/middleware_order.rs (1)
src/app.rs (2)
  • new (221-227)
  • new (330-330)
tests/metadata.rs (1)
src/app.rs (2)
  • new (221-227)
  • new (330-330)
examples/metadata_routing.rs (1)
src/app.rs (4)
  • new (221-227)
  • new (330-330)
  • id (187-187)
  • id (241-241)
tests/lifecycle.rs (2)
src/app.rs (9)
  • id (187-187)
  • id (241-241)
  • correlation_id (190-190)
  • correlation_id (243-243)
  • into_parts (193-193)
  • into_parts (231-237)
  • into_parts (245-245)
  • from_parts (196-196)
  • from_parts (247-249)
tests/routes.rs (4)
  • id (29-29)
  • correlation_id (31-31)
  • into_parts (33-39)
  • from_parts (41-47)
🔍 MCP Research (1 server)

Deepwiki:

  • The asynchronous messaging system integrates with the updated packet and envelope types, propagating optional correlation IDs through PushHandle and SessionRegistry. The WireframeProtocol trait hooks receive and manipulate frames with optional correlation IDs. (Protocol Customization)

  • The WireframeProtocol trait and ProtocolHooks structure support the updated envelope and packet types with optional correlation IDs. Hooks such as before_send and on_connection_setup operate on frames that include optional correlation IDs. (Protocol Customization)

  • The roadmap outlines the introduction of optional correlation IDs and the PacketParts struct as part of the transition to multi-packet streaming responses and advanced protocol features. This change is foundational for supporting streaming responses with correlation and fragmentation. (Future Roadmap)

🔇 Additional comments (20)
src/app.rs (5)

166-175: Example Packet impl aligns with optional correlation IDs

Keep this example minimal yet correct. The None correlation is appropriate for a custom envelope with no correlation.


176-182: from_parts example reconstructs correctly

The example reconstructs all fields; fine for illustrating round-tripping with PacketParts.


213-215: Envelope fields updated to Option are correct

Field visibility and types align with the new contract.


221-227: Envelope::new signature matches the new semantics

Constructor now cleanly accepts Option.


189-197: Confirm Option migration complete

  • No calls to Envelope::new pass a raw integer; the only invocation at src/app.rs:751 uses the correlation_id variable of type Option<u64>.
  • All impl Packet for … definitions—including tests and Envelope in src/app.rs—implement fn correlation_id(&self) -> Option<u64>.
tests/metadata.rs (1)

63-63: Ensure no raw integer correlation IDs in tests

  • Ran rg -n 'Envelope::new\([^,]+,\s*\d+\s*,\s*' tests – no matches found.
  • All tests now wrap correlation IDs in Some(...).
tests/correlation_id.rs (1)

15-17: Adopt Option correlation ids in streaming test

Yielding Some(cid) and asserting Some(cid) across frames validates propagation for streams. This complies with the optional correlation ID roadmap.

Also applies to: 23-23

tests/world.rs (1)

138-140: Propagate Option-based correlation ids in world helper and verification

The updates correctly carry and assert Some(self.cid) in all frames.

Also applies to: 153-157

tests/middleware_order.rs (1)

67-67: Adopt Option correlation ID in Envelope construction — LGTM

Creation with Some(7) aligns with the updated API and optional correlation ID design.

examples/ping_pong.rs (1)

60-60: Carry correlation ID on all error paths — LGTM

Error responses now include the request correlation ID (Option<u64>), matching the updated API and ensuring end-to-end correlation.

Also applies to: 65-69, 76-76, 82-86

tests/middleware.rs (1)

15-17: Echo service preserves correlation ID — LGTM

Extracting cid and passing it to ServiceResponse::new correctly preserves correlation IDs through the middleware chain.

README.md (1)

98-111: Update to PacketParts and optional correlation ID — LGTM

The example correctly reflects PacketParts and Option<u64> for correlation IDs, matching the refactored Packet trait.

tests/lifecycle.rs (1)

16-16: Migrate StateEnvelope to Option and PacketParts — LGTM

The trait implementation matches the updated Packet interface, and the envelope instance uses Some(0) as expected.

Also applies to: 105-121, 122-129, 143-143

tests/routes.rs (2)

14-14: Align imports with new Packet/PacketParts APIs

Import Packet and PacketParts from app to match the refactored trait surface. LGTM.


91-91: Assert correlation ID preservation

Assert against Some(99) after round-trip to prove correlation ID is preserved. LGTM.

src/middleware.rs (5)

39-42: Store optional correlation IDs in requests

Move to Option<u64> at the type level. This matches the new contract and avoids sentinel values. LGTM.


58-61: Return Option from request accessor

Return Option<u64> to reflect optionality. LGTM.


73-76: Store optional correlation IDs in responses

Track correlation IDs on responses as Option<u64>. LGTM.


81-86: Construct responses with optional correlation IDs

Pass through the optional correlation ID explicitly. LGTM.


11-12: Import PacketParts for struct-based envelope flow
Verified that middleware docs already reference optional correlation IDs and PacketParts (README.md 98, 106–109). LGTM.

Comment thread examples/metadata_routing.rs Outdated
Comment thread README.md
Comment thread src/app.rs
Comment thread src/app.rs Outdated
Comment thread src/middleware.rs
Comment thread tests/middleware.rs Outdated
Comment thread tests/middleware.rs Outdated
Comment thread tests/routes.rs Outdated
Comment thread tests/routes.rs
Comment thread tests/routes.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🔭 Outside diff range comments (1)
src/middleware.rs (1)

41-61: Expose a setter on ServiceRequest to allow middleware to attach/update correlation IDs.

Enable middleware to derive or amend correlation IDs (e.g., from headers/payload) before envelope construction.

 impl ServiceRequest {
@@
     pub fn correlation_id(&self) -> Option<u64> { self.correlation_id }
+
+    /// Set or clear the correlation identifier.
+    pub fn set_correlation_id(&mut self, correlation_id: Option<u64>) {
+        self.correlation_id = correlation_id;
+    }
♻️ Duplicate comments (9)
examples/metadata_routing.rs (4)

65-65: Replace unwrap with expect to follow linting guidelines

Use expect with a clear message.

-    let app = WireframeApp::new()
-        .unwrap()
+    let app = WireframeApp::new()
+        .expect("failed to create app")

92-92: Replace unwrap with expect to follow linting guidelines

Provide actionable failure context.

-    let payload = Ping.to_bytes().unwrap();
+    let payload = Ping.to_bytes().expect("failed to serialise Ping");

101-101: Replace unwrap with expect to follow linting guidelines

Provide actionable failure context.

-        .encode(&frame, &mut bytes)
-        .unwrap();
+        .encode(&frame, &mut bytes)
+        .expect("failed to encode frame");

106-106: Replace unwrap with expect to follow linting guidelines

Provide actionable failure context.

-    server_task.await.unwrap();
+    server_task.await.expect("server task join failed");
tests/middleware.rs (2)

58-61: Assert correlation_id in the first test to tighten guarantees

Add an assertion to ensure the response preserves Some(0).

     let response = wrapped.call(request).await.expect("middleware call failed");
     assert_eq!(response.frame(), &[1, 2, 3, b'!', b'?']);
+    assert_eq!(response.correlation_id(), Some(0));

63-86: Parameterise duplicated tests with rstest

Replace the duplicated None/Some cases with a single parameterised test.

use rstest::rstest;

#[rstest(correlation_id => [None, Some(0), Some(42)])]
#[tokio::test]
async fn middleware_modifies_request_and_response_preserves_cid(
    correlation_id: Option<u64>,
) {
    let service = EchoService;
    let mw = ModifyMiddleware;
    let wrapped = mw.transform(service).await;

    let request = ServiceRequest::new(vec![1, 2, 3], correlation_id);
    let response = wrapped.call(request).await.expect("middleware call failed");

    assert_eq!(response.frame(), &[1, 2, 3, b'!', b'?']);
    assert_eq!(response.correlation_id(), correlation_id);
}
README.md (1)

98-111: Document None correlation ID semantics alongside PacketParts

Explain that correlation_id: None denotes unsolicited or server‑initiated messages and cross‑link to the design doc. Add a short note under the Custom Envelopes example.

Example addition:

> Note: correlation_id: None denotes an unsolicited event or server‑initiated
> push. Handlers and middleware must preserve None as None rather than
> normalising to 0.
tests/lifecycle.rs (1)

128-156: Assert correlation_id propagation end‑to‑end

Decode the outgoing frame and assert the correlation ID is preserved as Some(0).

     let out = run_app(app, vec![frame.to_vec()], None)
         .await
         .expect("app run failed");
     assert!(!out.is_empty());
+    // Decode the first frame and verify correlation_id propagation
+    let mut buf = BytesMut::from(&out[0][..]);
+    let frame = LengthPrefixedProcessor::default()
+        .decode(&mut buf)
+        .expect("decode failed")
+        .expect("frame missing");
+    let (resp, _) = BincodeSerializer
+        .deserialize::<StateEnvelope>(&frame)
+        .expect("deserialize failed");
+    assert_eq!(resp.correlation_id, Some(0));
     assert_eq!(setup.load(Ordering::SeqCst), 1);
     assert_eq!(teardown.load(Ordering::SeqCst), 1);
src/middleware.rs (1)

81-86: Add a setter on ServiceResponse for correlation updates in middleware.

Make correlation updates explicit on the response path as well.

 impl ServiceResponse {
@@
     pub fn correlation_id(&self) -> Option<u64> { self.correlation_id }
+
+    /// Set or clear the correlation identifier.
+    pub fn set_correlation_id(&mut self, correlation_id: Option<u64>) {
+        self.correlation_id = correlation_id;
+    }

Also applies to: 96-99

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 36b86c1 and 88d54eb.

📒 Files selected for processing (9)
  • README.md (1 hunks)
  • docs/rust-binary-router-library-design.md (1 hunks)
  • examples/metadata_routing.rs (1 hunks)
  • src/app.rs (4 hunks)
  • src/middleware.rs (6 hunks)
  • tests/lifecycle.rs (3 hunks)
  • tests/middleware.rs (2 hunks)
  • tests/middleware_order.rs (3 hunks)
  • tests/routes.rs (5 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Function documentation must include clear examples demonstrating the usage and outcome of the function. Test documentation should omit examples where the example serves only to reiterate the test logic.
No single code file may be longer than 400 lines. Long switch statements or dispatch tables should be broken up by feature and constituents colocated with targets. Large blocks of test data should be moved to external data files.
Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status....

Files:

  • tests/middleware_order.rs
  • examples/metadata_routing.rs
  • tests/middleware.rs
  • src/middleware.rs
  • tests/routes.rs
  • tests/lifecycle.rs
  • src/app.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • tests/middleware_order.rs
  • examples/metadata_routing.rs
  • tests/middleware.rs
  • src/middleware.rs
  • tests/routes.rs
  • tests/lifecycle.rs
  • src/app.rs
**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.md: Documentation must use en-GB-oxendict spelling and grammar. (EXCEPTION: the naming of the LICENSE file, which is to be left unchanged for community consistency.)
Markdown paragraphs and bullet points must be wrapped at 80 columns.
Code blocks in Markdown files must be wrapped at 120 columns.
Tables and headings in Markdown files must not be wrapped.
Use dashes (-) for list bullets in Markdown files.
Use GitHub-flavoured Markdown footnotes ([^1]) for references and footnotes.

Files:

  • README.md
  • docs/rust-binary-router-library-design.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • README.md
  • docs/rust-binary-router-library-design.md
docs/**/*.md

📄 CodeRabbit Inference Engine (docs/contents.md)

Conventions for writing project documentation as described in the documentation style guide

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation text.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for example color.
Use the Oxford comma in documentation text.
Treat company names as collective nouns in documentation (e.g., "Lille Industries are expanding").
Write headings in sentence case in documentation.
Use Markdown headings (#, ##, ###, etc.) in order without skipping levels.
Follow markdownlint recommendations for Markdown files.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; use plaintext for non-code text.
Use - as the first level bullet and renumber lists when items change.
Prefer inline links using [text](url) or angle brackets around the URL; avoid reference-style links like [foo][bar].
Ensure blank lines before and after bulleted lists and fenced blocks in Markdown.
Ensure tables have a delimiter line below the header row in Markdown.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns in documentation.
Wrap code at 120 columns in documentation.
Do not wrap tables in documentation.
Use sequentially numbered footnotes referenced with [^1] and place definitions at the end of the file.
Where it adds clarity, include Mermaid diagrams in documentation.
When embedding figures, use ![alt text](path/to/image) and provide concise alt text describing the content.
Add a brief description before each Mermaid diagram in documentation for screen readers.

Document examples showing how to deprecate old message versions gracefully

Write the official documentation for the new features. Create separate guides for "Duplex Messaging & Pushes", "Streaming Responses", and "Message Fragmentation". Each guide must include runna...

Files:

  • docs/rust-binary-router-library-design.md
docs/**/*.{md,rs}

📄 CodeRabbit Inference Engine (docs/multi-packet-and-streaming-responses-design.md)

docs/**/*.{md,rs}: The official documentation and examples must exclusively use the declarative Response model for handler responses.
The async-stream pattern must be documented as the canonical approach for dynamic stream generation.

Files:

  • docs/rust-binary-router-library-design.md
🧬 Code Graph Analysis (4)
tests/middleware_order.rs (3)
src/app.rs (5)
  • new (221-227)
  • new (245-251)
  • new (357-357)
  • correlation_id (190-190)
  • correlation_id (235-235)
tests/lifecycle.rs (1)
  • correlation_id (112-112)
tests/routes.rs (1)
  • correlation_id (33-33)
examples/metadata_routing.rs (1)
src/app.rs (5)
  • new (221-227)
  • new (245-251)
  • new (357-357)
  • id (187-187)
  • id (232-232)
src/middleware.rs (3)
src/app.rs (7)
  • new (221-227)
  • new (245-251)
  • new (357-357)
  • correlation_id (190-190)
  • correlation_id (235-235)
  • from_parts (196-196)
  • from_parts (239-239)
src/extractor.rs (3)
  • new (120-120)
  • new (210-210)
  • req (269-269)
src/rewind_stream.rs (1)
  • new (25-31)
tests/routes.rs (3)
src/app.rs (15)
  • id (187-187)
  • id (232-232)
  • correlation_id (190-190)
  • correlation_id (235-235)
  • into_parts (193-193)
  • into_parts (237-237)
  • new (221-227)
  • new (245-251)
  • new (357-357)
  • from_parts (196-196)
  • from_parts (239-239)
  • default (297-310)
  • from (143-143)
  • from (272-272)
  • from (276-276)
wireframe_testing/src/helpers.rs (1)
  • drive_with_bincode (343-362)
src/message.rs (1)
  • from_bytes (50-55)
🔍 MCP Research (1 server)

Deepwiki:

  • docs/rust-binary-router-library-design.md: Introduces a new subsection "4.3.1 Packet Abstraction" describing the Packet trait representing transport frames, which can be decomposed into PacketParts for efficient handling and re-assembly. The default implementation is Envelope, which implements Packet and carries payload and metadata. The Packet trait defines methods id(), correlation_id() -> Option<u64>, into_parts() -> PacketParts, and from_parts(parts: PacketParts) -> Self. The PacketParts struct holds id, optional correlation_id, and payload. The Envelope struct contains these fields and implements Packet, providing a constructor and into_parts() method. This addition clarifies the abstraction for frame representation and decomposition, emphasizing reuse of PacketParts to avoid repetitive tuple unpacking during frame splitting.

  • src/app.rs: The Packet trait and related types have been refactored to use Option<u64> for the correlation ID instead of a plain u64. The trait method signatures were updated accordingly. The PacketParts struct was introduced to encapsulate id, optional correlation_id, and payload fields. The Envelope struct was flattened by removing the nested PacketHeader and directly storing id, correlation_id: Option<u64>, and payload. The Envelope implements Packet by delegating to these fields and converting to/from PacketParts. The PacketParts struct includes a constructor and an inherit_correlation method that sets the correlation ID if missing or logs a warning if mismatched. Logging statements in connection handling now include both id and optional correlation_id for improved context.

  • src/middleware.rs: The ServiceRequest struct's correlation_id field type was changed from u64 to Option<u64>, with constructor and accessor updated accordingly. The ServiceResponse struct was extended to include an optional correlation_id field, with constructor and accessor updated. In the RouteService<E: Packet> implementation of the Service trait, packet envelope creation now uses a PacketParts struct to encapsulate route ID, optional correlation ID, and payload bytes. Response construction extracts payload and correlation ID from the envelope's parts and passes both to ServiceResponse::new. These changes propagate the optional correlation ID through request and response types and unify packet envelope construction/deconstruction around PacketParts.

  • tests/routes.rs: The TestEnvelope struct was modified to change the correlation_id field from a u64 to an Option<u64>, and the msg field was renamed to payload. The Packet trait implementation for TestEnvelope was updated accordingly: the correlation_id() method now returns Option<u64>; into_parts() returns a PacketParts struct instead of a tuple; and from_parts() now takes a PacketParts struct instead of separate parameters. All test code creating TestEnvelope instances was updated to use Some(value) or None for correlation_id and to use payload instead of msg. Assertions checking correlation_id were changed to expect Option<u64>. Several new tests were added: one verifies handling of None correlation ID in a handler echo; another parametrized test checks propagation of various Option<u64> correlation IDs through a single frame; and a unit test verifies round-trip conversion between TestEnvelope and PacketParts. The changes affect serialization, deserialization, and frame processing logic to accommodate optional correlation IDs and renamed payload field, but no changes to control flow or error handling were introduced.

🔇 Additional comments (12)
tests/middleware_order.rs (1)

67-94: LGTM: correct use of optional correlation ID and PacketParts

Create Envelope with Some(7), round-trip via into_parts, and assert payload + correlation_id. This aligns with the new API.

tests/middleware.rs (1)

15-16: LGTM: propagate correlation_id through the service

Extract the Option from the request and pass it to ServiceResponse::new. This matches the new API surface.

tests/lifecycle.rs (1)

105-107: LGTM: adopt PacketParts and optional correlation ID in StateEnvelope

Use Option fields and implement Packet via PacketParts::{new, ...}. This matches the refactor and keeps functions concise without unnecessary return.

Also applies to: 109-125

docs/rust-binary-router-library-design.md (1)

532-535: Good addition; clearly explains the Packet/PacketParts intent.

The narrative concisely motivates PacketParts and its reuse.

src/middleware.rs (1)

314-322: Envelope construction via PacketParts is correct and future‑proof.

Building E from PacketParts and returning ServiceResponse from parts aligns with the refactor goals.

tests/routes.rs (4)

21-26: Update to Option<u64> and payload looks correct; trait impl matches new shape.

Accessors and parts conversions are sound; inlining small accessors is a nice touch.

Also applies to: 28-46


95-126: Solid None-path coverage.

This validates end-to-end propagation for missing correlation IDs.


185-227: Parametrised propagation test adds valuable breadth.

Good coverage across None and multiple Some values.


228-239: Round‑trip parts test is tight and useful.

This guards the conversion contract.

src/app.rs (3)

230-240: Accessor inlining and conversion via From are on point.

The Packet impl for Envelope is minimal and leverages the new conversions well.


242-269: PacketParts::new and inherit_correlation are well‑scoped.

Constructor and correlation inheritance (with a warning on mismatch) fit the design and logging guidance.


773-793: Preserve/validate correlation IDs on the response path.

Constructing parts with resp.correlation_id() and then calling .inherit_correlation(env.correlation_id) is the right ordering; logging includes both id and correlation_id.

Comment thread docs/rust-binary-router-library-design.md Outdated
Comment thread examples/metadata_routing.rs
Comment thread src/app.rs
Comment thread src/app.rs Outdated
Comment thread src/app.rs
Comment thread tests/middleware_order.rs Outdated
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Aug 8, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 8

♻️ Duplicate comments (1)
src/app.rs (1)

265-271: Conversions implemented – reduces duplication

From<Envelope> and From<PacketParts> centralise mapping logic exactly as previously requested.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88d54eb and 7e87c81.

📒 Files selected for processing (7)
  • README.md (2 hunks)
  • docs/api.md (1 hunks)
  • docs/roadmap.md (1 hunks)
  • docs/rust-binary-router-library-design.md (1 hunks)
  • src/app.rs (6 hunks)
  • src/middleware.rs (6 hunks)
  • tests/lifecycle.rs (4 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • README.md
  • docs/roadmap.md
  • docs/api.md
  • docs/rust-binary-router-library-design.md
**/*.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • tests/lifecycle.rs
  • src/app.rs
  • src/middleware.rs
🧬 Code Graph Analysis (3)
tests/lifecycle.rs (3)
tests/routes.rs (4)
  • id (30-30)
  • correlation_id (33-33)
  • into_parts (35-37)
  • from_parts (39-45)
src/app.rs (15)
  • id (181-181)
  • id (226-226)
  • correlation_id (184-184)
  • correlation_id (229-229)
  • into_parts (187-187)
  • into_parts (231-231)
  • new (215-221)
  • new (239-245)
  • new (347-347)
  • from_parts (190-190)
  • from_parts (233-233)
  • from (143-143)
  • from (266-266)
  • from (270-270)
  • default (291-304)
wireframe_testing/src/helpers.rs (1)
  • processor (22-22)
src/app.rs (3)
tests/lifecycle.rs (4)
  • correlation_id (112-112)
  • into_parts (114-116)
  • from_parts (118-124)
  • id (110-110)
tests/routes.rs (4)
  • correlation_id (33-33)
  • into_parts (35-37)
  • from_parts (39-45)
  • id (30-30)
src/metrics.rs (2)
  • inc_handler_errors (78-78)
  • inc_handler_errors (81-81)
src/middleware.rs (1)
src/app.rs (7)
  • new (215-221)
  • new (239-245)
  • new (347-347)
  • correlation_id (184-184)
  • correlation_id (229-229)
  • from_parts (190-190)
  • from_parts (233-233)
🪛 LanguageTool
docs/api.md

[typographical] ~11-~11: Consider using an em dash in dialogues and enumerations.
Context: ...relation_id, payload); ``` - id: u32 – frame identifier - `correlation_id: Opt...

(DASH_RULE)

🔇 Additional comments (10)
tests/lifecycle.rs (1)

155-165: Validate run_app contract before casting bytes

The test assumes run_app returns a single contiguous Vec<u8>, yet the API previously supplied a Vec<Vec<u8>>. Passing a slice of vectors to BytesMut::from will not compile. Confirm the return type and adapt:

-let mut buf = BytesMut::from(&out[..]);
+let mut buf = BytesMut::from(&out);

or iterate if multiple frames are possible.

src/middleware.rs (4)

41-52: Optional correlation ID wiring looks correct

ServiceRequest now stores an Option<u64> and the ctor initialises it cleanly.


58-60: Accessor is fine

The getter obeys naming and returns Option<u64> as expected.


74-86: ServiceResponse gains correlation-id support correctly

Constructor and storage align with the request side.


319-327: Good use of PacketParts::new

Switching to the helper collapses three lines of boiler-plate and keeps the call site readable.

src/app.rs (4)

166-174: Example now matches public API

Doc test uses PacketParts::new and correct field names.


183-191: Trait signature update is sound

Returning Option<u64> lines up with wire format and avoids sentinel values.


622-624: Log context added

Connection-level error now carries a correlation placeholder, improving trace consistency.


751-783: Logging enrichments are consistent

All warn paths now include id and optional correlation_id, aiding diagnostics.

docs/roadmap.md (1)

158-166: Record completion of packet decomposition and optional correlation identifiers

Aligns with the implemented API and uses consistent terminology (“server‑initiated push”). No further changes required.

Comment thread docs/api.md Outdated
Comment thread docs/rust-binary-router-library-design.md
Comment thread docs/rust-binary-router-library-design.md
Comment thread README.md
Comment thread README.md Outdated
Comment thread src/app.rs
Comment thread src/app.rs
Comment thread src/middleware.rs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (2)
src/app.rs (2)

153-176: Fix doctest imports for PacketParts in the Packet trait example

Import PacketParts so the doctest compiles.

-/// use wireframe::{app::Packet, message::Message};
+/// use wireframe::{app::{Packet, PacketParts}, message::Message};

324-349: Fix doctest imports in WireframeApp::new example

Import PacketParts in the example so doctests compile.

-    /// use wireframe::app::{Packet, WireframeApp};
+    /// use wireframe::app::{Packet, PacketParts, WireframeApp};
♻️ Duplicate comments (2)
src/app.rs (2)

1-792: Decompose this module to meet the 400-line limit

Split by responsibility (packet.rs, envelope.rs, builder.rs, protocol.rs, io.rs, connection.rs). An issue already tracks this.

Link: #291


193-199: Avoid exposing PacketParts fields publicly to protect invariants

Hide fields and expose getters to prevent external mutation bypassing inherit_correlation invariants. This will require updating call sites (tests and examples).

If you want to stage this without breaking external users, first add getters and deprecate direct field access, then make fields private in a follow-up release.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e87c81 and 47e3dfe.

📒 Files selected for processing (3)
  • src/app.rs (6 hunks)
  • src/middleware.rs (6 hunks)
  • tests/packet_parts.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Function documentation must include clear examples demonstrating the usage and outcome of the function. Test documentation should omit examples where the example serves only to reiterate the test logic.
No single code file may be longer than 400 lines. Long switch statements or dispatch tables should be broken up by feature and constituents colocated with targets. Large blocks of test data should be moved to external data files.
Clippy warnings MUST be disallowed.
Fix any warnings emitted during tests in the code itself rather than silencing them.
Where a function is too long, extract meaningfully named helper functions adhering to separation of concerns and CQRS.
Where a function has too many parameters, group related parameters in meaningfully named structs.
Where a function is returning a large error consider using Arc to reduce the amount of data returned.
Write unit and behavioural tests for new functionality. Run both before and after making any change.
Every module must begin with a module level (//! ) comment explaining the module's purpose and utility.
Document public APIs using Rustdoc comments (///) so documentation can be generated with cargo doc.
Prefer immutable data and avoid unnecessary mut bindings.
Handle errors with the Result type instead of panicking where feasible.
Avoid unsafe code unless absolutely necessary and document any usage clearly.
Place function attributes after doc comments.
Do not use return in single-line functions.
Use predicate functions for conditional criteria with more than two branches.
Lints must not be silenced except as a last resort.
Lint rule suppressions must be tightly scoped and include a clear reason.
Prefer expect over allow.
Prefer .expect() over .unwrap().
Use concat!() to combine long string literals rather than escaping newlines with a backslash.
Prefer semantic error enums. Derive std::error::Error (via the thiserror crate) for any condition the caller might inspect, retry, or map to an HTTP status....

Files:

  • tests/packet_parts.rs
  • src/middleware.rs
  • src/app.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • tests/packet_parts.rs
  • src/middleware.rs
  • src/app.rs
🧬 Code Graph Analysis (2)
tests/packet_parts.rs (1)
src/app.rs (10)
  • new (215-221)
  • new (239-245)
  • new (350-350)
  • from (143-143)
  • from (269-269)
  • from (273-273)
  • id (181-181)
  • id (226-226)
  • correlation_id (184-184)
  • correlation_id (229-229)
src/app.rs (3)
tests/lifecycle.rs (4)
  • correlation_id (112-112)
  • into_parts (114-116)
  • from_parts (118-124)
  • id (110-110)
tests/routes.rs (4)
  • correlation_id (33-33)
  • into_parts (35-37)
  • from_parts (39-45)
  • id (30-30)
src/metrics.rs (2)
  • inc_handler_errors (78-78)
  • inc_handler_errors (81-81)
🔍 MCP Research (1 server)

Deepwiki:

  • Document [docs/rust-binary-router-library-design.md] describes the introduction of a Packet trait representing transport frames, decomposable into PacketParts for efficient handling and re-assembly. The default implementation is Envelope, which implements Packet and carries payload and metadata. PacketParts holds id: u32, correlation_id: Option<u64>, and payload: Vec<u8>. The Envelope struct no longer contains a nested PacketHeader but directly stores these fields. The Packet trait's methods correlation_id(), into_parts(), and from_parts() are updated accordingly. PacketParts includes a constructor and an inherit_correlation method. (docs/rust-binary-router-library-design.md)

  • Document [docs/api.md] adds API documentation for the PacketParts struct, decomposing a packet into id: u32, correlation_id: Option<u64> (where None indicates unsolicited event or server push), and payload: Vec<u8>. It includes example Rust code demonstrating creation and conversion to/from PacketParts. It notes that None correlation IDs propagate to ensure server-originated packets do not carry unintended correlation identifiers. (docs/api.md)

  • Document [src/app.rs] details updates to the Packet trait and related types to use Option<u64> for correlation IDs instead of u64. Trait method signatures for correlation_id(), into_parts(), and from_parts() use Option<u64> and PacketParts. The Envelope struct fields remove PacketHeader and directly include id, correlation_id: Option<u64>, and payload. Envelope implements Packet by delegating to these fields and converting to/from PacketParts. The PacketParts struct is added with methods new() and inherit_correlation(). Logging and routing logic include optional correlation IDs. (src/app.rs)

  • Document [src/middleware.rs] describes changes to ServiceRequest and ServiceResponse structs to use Option<u64> for correlation IDs. ServiceRequest's correlation_id field type changed from u64 to Option<u64>, with constructor and accessor updated accordingly. ServiceResponse was extended with an optional correlation_id field, constructor, setter, and accessor updated to handle this. The RouteService<E: Packet> implementation uses PacketParts to encapsulate route ID, optional correlation ID, and payload bytes when creating envelopes and constructing responses. (src/middleware.rs)

🔇 Additional comments (9)
tests/packet_parts.rs (1)

5-14: LGTM: Round-trip conversion behaves correctly

The assertions cover id, correlation_id and payload. This validates Envelope ↔ PacketParts conversions as intended.

src/middleware.rs (2)

41-61: Propagate optional correlation ID through requests

Switching ServiceRequest to Option<u64> and exposing correlation_id() is correct and aligns with the updated Packet trait semantics.


75-106: Expose correlation on responses with a fluent setter

The new ServiceResponse correlation field, accessor, and chainable #[must_use] setter are well-shaped for middleware.

src/app.rs (6)

183-191: Packet trait refactor to Option and PacketParts is on point

The trait surface matches the PR objective and the wider design. Method signatures and semantics are coherent.


236-245: PacketParts::new is correct and keeps construction consistent

Constructor looks good and centralises initialisation.


268-274: Prefer From/Into conversions to slim Packet impls

Using From<Envelope> and From<PacketParts> is the right shape; the Packet impl forwarding to these reads cleanly.


625-627: Include correlation context in termination logs

Good: termination warns include an explicit correlation_id = ?None::<u64> for consistency.


753-755: Include correlation context in deserialisation failure logs

Good: warning includes a correlation field (None) and the error. This aligns logging across the module.


766-786: Route through optional correlation correctly

  • Build ServiceRequest with the incoming correlation, pass through handler, and construct the response via PacketParts::inherit_correlation to ensure presence/correction.
  • Log handler and DLQ errors with id and correlation context.

This is the intended propagation model.

Comment thread src/app.rs
Comment thread src/app.rs
Comment thread src/middleware.rs
Comment thread tests/packet_parts.rs Outdated
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This PR introduces a significant architectural improvement to the Wireframe library by implementing optional correlation IDs and introducing the PacketParts struct. The changes replace raw u64 correlation_id fields with Option<u64> throughout the codebase, making the optional nature of correlation tracking explicit. This design allows the system to properly distinguish between solicited responses (with correlation IDs) and unsolicited events or server-initiated pushes (with None correlation IDs).

The PacketParts struct serves as a unified container for packet components (id, correlation_id, payload), replacing the previous tuple-based approach for packet decomposition. This provides better type safety and eliminates repetitive tuple unpacking. The Envelope struct was flattened by removing the nested PacketHeader and directly embedding the packet fields.

Key changes include:

  • Updated the Packet trait to use PacketParts for into_parts() and from_parts() methods
  • Enhanced ServiceRequest and ServiceResponse to propagate correlation IDs through the middleware pipeline
  • Added sophisticated correlation ID inheritance logic with inherit_correlation() method
  • Enriched logging throughout the system to include correlation IDs alongside message IDs
  • Updated all tests, examples, and documentation to work with the new optional correlation ID system

The changes maintain backward compatibility while providing cleaner abstractions and better debugging capabilities through improved traceability.

Important Files Changed

File Changes
Filename Score Overview
src/app.rs 4/5 Core implementation of PacketParts struct and optional correlation ID system with inheritance logic
src/middleware.rs 4/5 Updated middleware system to propagate optional correlation IDs through request/response cycle
tests/packet_parts.rs 5/5 New comprehensive test suite for PacketParts struct and correlation ID inheritance
tests/routes.rs 5/5 Updated routing tests to support optional correlation IDs with comprehensive parameterized testing
tests/lifecycle.rs 4/5 Updated lifecycle tests to use new PacketParts API and verify correlation ID propagation
tests/middleware.rs 5/5 Enhanced middleware tests with parameterized correlation ID testing using rstest
tests/middleware_order.rs 5/5 Updated middleware ordering tests to verify correlation ID preservation through middleware chains
tests/correlation_id.rs 5/5 Simple test update to use optional correlation IDs in streaming scenarios
tests/metadata.rs 5/5 Minimal safe updates to use Some(0) for correlation_id in metadata parsing tests
tests/world.rs 5/5 Updated Cucumber BDD test infrastructure to work with optional correlation IDs
examples/ping_pong.rs 5/5 Updated ping/pong example to extract and propagate correlation IDs through all response paths
examples/metadata_routing.rs 5/5 Updated example to use None for correlation IDs and improved error handling with .expect()
README.md 5/5 Updated documentation to demonstrate new PacketParts API and optional correlation ID usage
docs/api.md 5/5 New documentation file explaining PacketParts struct usage and None correlation ID semantics
docs/rust-binary-router-library-design.md 5/5 Added new section documenting the Packet abstraction with UML diagram
docs/roadmap.md 5/5 Updated roadmap to mark Packet decomposition feature as complete with proper formatting

Confidence score: 4/5

  • This PR introduces significant architectural improvements with good test coverage and documentation, but requires careful attention due to the complexity of the changes
  • Score reflects thorough implementation of optional correlation IDs and PacketParts with comprehensive testing, though the wide-reaching nature of changes warrants careful review
  • Pay close attention to src/app.rs and src/middleware.rs for the core correlation ID inheritance logic and middleware propagation patterns

Context used:

Rule - Prefer .expect() over .unwrap() (link)

16 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

Greptile Summary

This review covers only the changes made since the last review (commit 020adc9), not the entire PR.

The recent changes primarily focus on improving API encapsulation and consistency. The most significant change is making the PacketParts struct fields private and providing controlled access through public getter methods (id(), correlation_id(), payload()). This follows proper encapsulation principles and prevents external code from directly mutating internal state.

The changes also include updates to all dependent code that was using direct field access - tests, examples, and middleware code have been refactored to use the new accessor methods instead. Documentation has been enhanced throughout with better examples for the Packet trait and improved documentation for the inherit_correlation method. Minor cosmetic improvements include fixing hyphenation consistency ("re-assembly" → "reassembly") and standardizing dash usage in documentation lists from en-dashes to em-dashes.

These changes maintain backward compatibility through existing From trait implementations while establishing a more stable and maintainable public API that can evolve without breaking client code.

Important Files Changed

File Changes
Filename Score Overview
src/app.rs 5/5 Made PacketParts fields private with public accessor methods for better encapsulation
tests/packet_parts.rs 5/5 Updated tests to use new PacketParts accessor methods instead of direct field access
tests/routes.rs 5/5 Refactored TestEnvelope implementation to use PacketParts accessor methods
tests/lifecycle.rs 5/5 Updated StateEnvelope to use new PacketParts API with getter methods
tests/middleware_order.rs 5/5 Adapted test to use unified Packet::into_parts() API instead of deprecated Envelope methods
src/middleware.rs 5/5 Refactored RouteService to use PacketParts accessor methods consistently
docs/api.md 5/5 Minor typography improvement replacing en-dashes with em-dashes
docs/rust-binary-router-library-design.md 5/5 Fixed hyphenation consistency and added None correlation ID semantics
README.md 5/5 Updated documentation to demonstrate new PacketParts accessor methods

Confidence score: 5/5

  • This PR is extremely safe to merge with minimal risk of breaking existing functionality
  • Score reflects proper encapsulation improvements and comprehensive test updates that maintain backward compatibility
  • No files require special attention as all changes follow consistent patterns and maintain existing behavior

9 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 11, 2025

@coderabbitai review

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 11, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 11, 2025

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Copy Markdown

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 11, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
examples/metadata_routing.rs (2)

65-65: Good replacement of unwrap() with expect() and improved error messages.

This follows the project guideline to prefer expect() with context.

Also applies to: 76-76, 85-85, 101-101, 106-106


92-92: Use of “serialize” matches en‑GB‑oxendict “-ize” spelling.

Spelling now aligns with the documented style.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7325a74 and 6bda6e0.

📒 Files selected for processing (3)
  • README.md (3 hunks)
  • docs/rust-binary-router-library-design.md (1 hunks)
  • examples/metadata_routing.rs (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • examples/metadata_routing.rs
**/*.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/rust-binary-router-library-design.md
  • README.md
🧬 Code Graph Analysis (1)
examples/metadata_routing.rs (2)
src/app.rs (7)
  • new (215-221)
  • new (239-245)
  • new (376-376)
  • id (181-181)
  • id (226-226)
  • id (248-248)
  • payload (254-254)
tests/world.rs (1)
  • spawn (32-64)
🔍 MCP Research (1 server)

Deepwiki:

🔇 Additional comments (3)
examples/metadata_routing.rs (1)

55-55: Boldly keep None for absent correlation IDs.

This correctly aligns the example with the Packet API’s Option and with repository conventions where None means “no correlation”.

README.md (2)

123-126: Keep None semantics explicit.

This note correctly standardises on None (not Some(0)) for “no correlation” and links to PacketParts details.


98-114: Update the accompanying snippet to use expect() instead of unwrap().

The custom envelope implementation is correct. Also adjust subsequent chained calls to avoid unwrap() in examples, keeping examples consistent with the guideline to prefer expect().

Example adjustment (illustrative):

-let app = WireframeApp::<_, _, MyEnv>::new()
-    .unwrap()
+let app = WireframeApp::<_, _, MyEnv>::new()
+    .expect("failed to create app")
     .route(1, std::sync::Arc::new(|env: &MyEnv| Box::pin(async move { /* ... */ })))
-    .unwrap();
+    .expect("failed to add route");

Likely an incorrect or invalid review comment.

Comment thread docs/rust-binary-router-library-design.md
Comment thread README.md Outdated
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🔭 Outside diff range comments (1)
src/app.rs (1)

146-181: Update docs to match the PacketParts API

No tuple-based signatures remain, but examples still refer to a msg field where the trait now uses payload. Rename these to keep docs and code in sync:

  • In docs/message-versioning.md (lines 48–50), change
    version: Option<u16>,
    msg: Vec<u8>,
    to
    version: Option<u16>,
    payload: Vec<u8>,
  • Search other docs for direct msg: fields in envelope-type examples or PacketParts usage and update them to payload:.
♻️ Duplicate comments (1)
src/app.rs (1)

1-826: Decompose module exceeding 400-line limit (tracked)

Split src/app.rs by responsibility as previously suggested. This file still violates the ≤400-line guideline.

Issue already created (Refactor app.rs: decompose module exceeding 400-line limit). Do not block this PR further on structure; follow up in the linked issue.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6bda6e0 and 1a94d00.

📒 Files selected for processing (2)
  • src/app.rs (8 hunks)
  • tests/lifecycle.rs (3 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Use precise names; boolean names should start with is/has/should
Use en-GB-oxendict spelling and grammar in comments
Function documentation must include clear examples; test documentation should omit redundant examples
Keep code files ≤ 400 lines; split long switch/dispatch logic by feature; move large test data to external files
Disallow Clippy warnings
Fix warnings emitted during tests in code rather than silencing them
Extract helper functions for long functions; adhere to separation of concerns and CQRS
Group related parameters into meaningful structs when functions have many parameters
Consider using Arc for large error returns to reduce data size
Each Rust module must begin with a module-level //! comment describing purpose and utility
Document public APIs with Rustdoc /// comments to enable cargo doc generation
Prefer immutable data; avoid unnecessary mut
Handle errors with Result instead of panicking where feasible
Avoid unsafe code unless necessary and document any usage clearly
Place function attributes after doc comments
Do not use return in single-line functions
Use predicate functions for conditional criteria with more than two branches
Do not silence lints except as a last resort
Lint suppressions must be tightly scoped and include a clear reason
Prefer #[expect(..)] over #[allow(..)] for lints
Prefer .expect() over .unwrap()
Use concat!() to combine long string literals rather than escaping newlines
Prefer single-line function bodies where appropriate (e.g., pub fn new(id: u64) -> Self { Self(id) })
Prefer semantic error enums deriving std::error::Error via thiserror for inspectable conditions

Files:

  • tests/lifecycle.rs
  • src/app.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • tests/lifecycle.rs
  • src/app.rs
{src,tests}/**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

Write unit and behavioural tests for new functionality

Files:

  • tests/lifecycle.rs
  • src/app.rs
tests/**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

tests/**/*.rs: Use rstest fixtures for shared setup
Replace duplicated tests with #[rstest(...)] parameterised cases
Prefer mockall for mocks/stubs

Files:

  • tests/lifecycle.rs
🧬 Code Graph Analysis (2)
tests/lifecycle.rs (3)
tests/routes.rs (9)
  • id (30-30)
  • correlation_id (33-33)
  • into_parts (35-37)
  • from_parts (39-48)
  • BincodeSerializer (89-90)
  • BincodeSerializer (122-123)
  • BincodeSerializer (170-171)
  • BincodeSerializer (178-179)
  • BincodeSerializer (224-225)
src/app.rs (17)
  • id (184-184)
  • id (229-229)
  • id (251-251)
  • correlation_id (187-187)
  • correlation_id (232-232)
  • correlation_id (254-254)
  • into_parts (190-190)
  • into_parts (234-234)
  • new (218-224)
  • new (242-248)
  • new (379-379)
  • from_parts (193-193)
  • from_parts (236-236)
  • payload (257-257)
  • from (143-143)
  • from (293-293)
  • from (297-302)
wireframe_testing/src/helpers.rs (1)
  • processor (22-22)
src/app.rs (3)
tests/lifecycle.rs (4)
  • correlation_id (112-112)
  • into_parts (114-116)
  • from_parts (118-127)
  • id (110-110)
src/middleware.rs (9)
  • correlation_id (60-60)
  • correlation_id (105-105)
  • new (22-22)
  • new (47-52)
  • new (88-93)
  • new (151-151)
  • new (202-202)
  • new (288-298)
  • id (312-312)
tests/routes.rs (4)
  • correlation_id (33-33)
  • into_parts (35-37)
  • from_parts (39-48)
  • id (30-30)
🔍 MCP Research (1 server)

Deepwiki:

  • Page: Overview — The README example in the Overview page documents an older Packet trait API where into_parts() returns a raw tuple (u32, Vec) rather than PacketParts (see "Custom Envelope Types" snippet showing fn into_parts(self) -> (u32, Vec) and fn from_parts(id: u32, data: Vec) -> Self). (docs from leynos/wireframe: Page "Overview")
  • Page: API Reference — The API Reference page describes the Packet trait and explicitly shows into_parts() -> (u32, Vec) and from_parts(id: u32, msg: Vec) -> Self in its "Message Processing APIs" / "Core Traits" section, indicating the repository's documented API includes the older tuple-based packet decomposition. (docs from leynos/wireframe: Page "API Reference")
⏰ Context from checks skipped due to timeout of 120000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-test
🔇 Additional comments (7)
tests/lifecycle.rs (3)

102-107: Packet impl for test envelope aligns with new API

Implement Packet using PacketParts::new and accessors. The correlation_id: Option and payload naming are correct and consistent with the refactor.

Also applies to: 109-128


149-151: Encode with shared processor helper is correct

Use processor() for encoding to keep symmetry with the app’s frame processor and avoid drift. Good.


153-167: Retain existing buffer conversion
run_app returns io::Result<Vec<u8>>, so out is a single Vec<u8>. Decoding with BytesMut::from(&out[..]) is correct—drop the indexing suggestion.

src/app.rs (4)

154-177: Update examples to PacketParts and payload is correct

Demonstrate Packet::into_parts/from_parts using PacketParts::new and payload. This matches the new public surface.


187-194: Trait surface changes are coherent

Expose correlation_id() -> Option, into_parts(self) -> PacketParts, and from_parts(parts) -> Self. This unifies decomposition across envelope types as intended.


210-223: Envelope flattening and conversions look correct

  • Envelope stores id, correlation_id: Option, payload directly, matching docs/tests.
  • Packet impl delegates via From conversions; From/From centralise mapping. Good.

Also applies to: 227-237, 292-303


654-656: Tracing now includes correlation context; keep it consistent

  • Maintain correlation context consistently across warn! logs (done here).
  • Good use of correlation_id = ?None:: where not yet known.

Also applies to: 783-791, 795-803, 814-820

Comment thread src/app.rs
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

3 files reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (2)
src/app.rs (2)

153-181: Fix doctest imports to include PacketParts

Import PacketParts in the example; otherwise the doctest cannot resolve the symbol.

-/// use wireframe::{
-///     app::{Packet, PacketParts},
-///     message::Message,
-/// };
+/// use wireframe::{
+///     app::{Packet, PacketParts},
+///     message::Message,
+/// };

And in the later example:

-/// use wireframe::app::{Packet, WireframeApp};
+/// use wireframe::app::{Packet, PacketParts, WireframeApp};

321-338: Minor doc style nit: British English spelling in docs

Keep British English with Oxford -ize/-our in documentation comments. “Initializes” is acceptable (Oxford -ize), but audit nearby comments for stray Americanisms in follow‑ups.

♻️ Duplicate comments (1)
src/app.rs (1)

1-200: Split the module to stay within the 400‑line limit

Decompose this file by responsibility as already tracked in issue #291; keep Packet/PacketParts, Envelope, builder, protocol hooks, I/O, and connection handling in separate modules.

Also applies to: 315-395

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a94d00 and e7dc1a4.

📒 Files selected for processing (3)
  • README.md (3 hunks)
  • docs/rust-binary-router-library-design.md (1 hunks)
  • src/app.rs (8 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.rs: Use precise names; boolean names should start with is/has/should
Use en-GB-oxendict spelling and grammar in comments
Function documentation must include clear examples; test documentation should omit redundant examples
Keep code files ≤ 400 lines; split long switch/dispatch logic by feature; move large test data to external files
Disallow Clippy warnings
Fix warnings emitted during tests in code rather than silencing them
Extract helper functions for long functions; adhere to separation of concerns and CQRS
Group related parameters into meaningful structs when functions have many parameters
Consider using Arc for large error returns to reduce data size
Each Rust module must begin with a module-level //! comment describing purpose and utility
Document public APIs with Rustdoc /// comments to enable cargo doc generation
Prefer immutable data; avoid unnecessary mut
Handle errors with Result instead of panicking where feasible
Avoid unsafe code unless necessary and document any usage clearly
Place function attributes after doc comments
Do not use return in single-line functions
Use predicate functions for conditional criteria with more than two branches
Do not silence lints except as a last resort
Lint suppressions must be tightly scoped and include a clear reason
Prefer #[expect(..)] over #[allow(..)] for lints
Prefer .expect() over .unwrap()
Use concat!() to combine long string literals rather than escaping newlines
Prefer single-line function bodies where appropriate (e.g., pub fn new(id: u64) -> Self { Self(id) })
Prefer semantic error enums deriving std::error::Error via thiserror for inspectable conditions

Files:

  • src/app.rs

⚙️ CodeRabbit Configuration File

**/*.rs: * Seek to keep the cyclomatic complexity of functions no more than 12.

  • Adhere to single responsibility and CQRS

  • Place function attributes after doc comments.

  • Do not use return in single-line functions.

  • Move conditionals with >2 branches into a predicate function.

  • Avoid unsafe unless absolutely necessary.

  • Every module must begin with a //! doc comment that explains the module's purpose and utility.

  • Comments and docs must follow en-GB-oxendict (-ize / -our) spelling and grammar

  • Lints must not be silenced except as a last resort.

    • #[allow] is forbidden.
    • Only narrowly scoped #[expect(lint, reason = "...")] is allowed.
    • No lint groups, no blanket or file-wide suppression.
    • Include FIXME: with link if a fix is expected.
  • Where code is only used by specific features, it must be conditionally compiled or a conditional expectation for unused_code applied.

  • Use rstest fixtures for shared setup and to avoid repetition between tests.

  • Replace duplicated tests with #[rstest(...)] parameterised cases.

  • Prefer mockall for mocks/stubs.

  • Prefer .expect() over .unwrap()

  • Ensure that any API or behavioural changes are reflected in the documentation in docs/

  • Ensure that any completed roadmap steps are recorded in the appropriate roadmap in docs/

  • Files must not exceed 400 lines in length

    • Large modules must be decomposed
    • Long match statements or dispatch tables should be decomposed by domain and collocated with targets
    • Large blocks of inline data (e.g., test fixtures, constants or templates) must be moved to external files and inlined at compile-time or loaded at run-time.

Files:

  • src/app.rs
{src,tests}/**/*.rs

📄 CodeRabbit Inference Engine (AGENTS.md)

Write unit and behavioural tests for new functionality

Files:

  • src/app.rs
docs/**/*.md

📄 CodeRabbit Inference Engine (docs/documentation-style-guide.md)

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation text.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for example color.
Use the Oxford comma in documentation text.
Treat company names as collective nouns in documentation (e.g., "Lille Industries are expanding").
Write headings in sentence case in documentation.
Use Markdown headings (#, ##, ###, etc.) in order without skipping levels.
Follow markdownlint recommendations for Markdown files.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; use plaintext for non-code text.
Use - as the first level bullet and renumber lists when items change.
Prefer inline links using [text](url) or angle brackets around the URL; avoid reference-style links like [foo][bar].
Ensure blank lines before and after bulleted lists and fenced blocks in Markdown.
Ensure tables have a delimiter line below the header row in Markdown.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns in documentation.
Wrap code at 120 columns in documentation.
Do not wrap tables in documentation.
Use sequentially numbered footnotes referenced with [^1] and place definitions at the end of the file.
Where it adds clarity, include Mermaid diagrams in documentation.
When embedding figures, use ![alt text](path/to/image) and provide concise alt text describing the content.
Add a brief description before each Mermaid diagram in documentation for screen readers.

Document examples showing how to deprecate old message versions gracefully

Write the official documentation for the new features. Create separate guides for "Duplex Messaging & Pushes", "Streaming Responses", and "Message Fragmentation". Each guide must include runnable examples and explain the relevant concepts and APIs.

docs/**/*.md: Use docs/ markdown ...

Files:

  • docs/rust-binary-router-library-design.md
docs/**/*.{md,rs}

📄 CodeRabbit Inference Engine (docs/multi-packet-and-streaming-responses-design.md)

docs/**/*.{md,rs}: The official documentation and examples must exclusively use the declarative Response model for handler responses.
The async-stream pattern must be documented as the canonical approach for dynamic stream generation.

Files:

  • docs/rust-binary-router-library-design.md
**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.md: Markdown paragraphs and bullet points must be wrapped at 80 columns
Markdown code blocks must be wrapped at 120 columns
Do not wrap tables and headings in Markdown
Use dashes (-) for list bullets in Markdown
Use GitHub-flavoured Markdown footnotes ([^1])

Files:

  • docs/rust-binary-router-library-design.md
  • README.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/rust-binary-router-library-design.md
  • README.md
🧬 Code Graph Analysis (1)
src/app.rs (2)
tests/lifecycle.rs (4)
  • correlation_id (112-112)
  • into_parts (114-116)
  • from_parts (118-127)
  • id (110-110)
tests/routes.rs (4)
  • correlation_id (33-33)
  • into_parts (35-37)
  • from_parts (39-48)
  • id (30-30)
🔍 MCP Research (2 servers)

Deepwiki:

  • Document [CI/CD and Development Workflow]: The repository defines GitHub Actions workflows including .github/workflows/ci.yml (main CI) and .github/workflows/advanced-tests.yml (advanced/scheduled tests) used to run formatting, clippy, tests, and coverage steps. (docs: CI/CD and Development Workflow)
  • Document [Observability and Monitoring]: The project exports Prometheus-ready metrics with concrete metric names such as wireframe_connections_active, wireframe_frames_processed_total, wireframe_push_queue_depth, wireframe_pushes_dropped_total, and wireframe_request_latency_seconds. (docs: Observability and Monitoring)
  • Document [Asynchronous Messaging]: The SessionRegistry stores Weak entries (DashMap of ConnectionId → Weak) so lookups upgrade weak refs and prune dead connections; PushHandle uses token-bucket rate limiting and supports Dead Letter Queue routing for full queues. (docs: Asynchronous Messaging)

Context7:
Selected library ID: NONE — no relevant Context7 library match found

Reason: The resolve step returned no library matching the PR title or the wireframe repository. Please provide one of:

  • the exact Context7-compatible library ID (format: /org/project or /org/project/version), or
  • a clearer library/package name such as "leynos/wireframe" or the repository URL so I can resolve and fetch docs/issues for the specific codebase.
🔇 Additional comments (15)
docs/rust-binary-router-library-design.md (1)

537-544: LGTM: Correlation identifier semantics and streaming note are clear

The explanation that None denotes unsolicited events or server‑initiated pushes, plus the linkage/explicit EOS guidance for streaming, reads well and matches the updated API.

src/app.rs (11)

186-194: Packet trait surface looks sound

The trait shape (id(), optional correlation_id(), into_parts()/from_parts()) is orthogonal and enables envelope-agnostic routing. No issues.


196-203: Keep PacketParts encapsulated; API matches docs

Private fields with constructor/accessors are correct for invariants and future evolution. No issues.


209-224: Envelope flattening and Option correlation are correct

Flattening Envelope and adopting Option<u64> aligns with the PR objective and simplifies usage. Constructor shape is appropriate.


227-237: Delegate via From/Into to avoid duplication

Using From<Envelope> for PacketParts and its inverse to implement Packet keeps mapping centralised and tidy. Good.


259-290: Correlation inheritance behaviour is robust and well‑instrumented

The function now fills missing CIDs and overwrites mismatches after a warn!, including packet id for traceability. Examples reflect behaviour. Good.


293-304: Conversions are clean and side‑effect free

Using accessors in From<PacketParts> for Envelope avoids field leakage and keeps invariants intact.


626-637: Parse fast path with fallback is appropriate

Parsing via FrameMetadata::parse with a safe fallback to full deserialisation is correct. Error boxing is acceptable here.


655-657: Enrich connection error logs with correlation context

Including correlation_id = ?None::<u64> ensures consistent log shape. This matches the logging guidance and previous feedback. Good.


777-794: Deserialisation failure handling is correct and bounded

Warn, increment error metric, cap via MAX_DESER_FAILURES, and continue. Including the correlation context (None) keeps log shape consistent.


796-804: Response correlation propagation is correct

Build PacketParts with handler output, inherit/overwrite CID from request as needed, then convert to Envelope. Logging includes id and correlation_id. This addresses past ambiguity.


815-821: Good: include id and correlation_id in handler/no‑route warnings

Keep these fields in all warnings for traceability.

README.md (3)

98-114: LGTM: Custom envelope example updated to PacketParts and optional CID

The example now imports PacketParts, uses Option<u64>, and constructs via PacketParts::new(...). Access via accessors is correct.


123-126: LGTM: Clarify None correlation identifier semantics with cross‑reference

The added note and link to PacketParts documentation are clear and consistent with the design.


293-295: LGTM: Link the example title to its file

The hyperlink improves discoverability; keep this pattern for other examples.

Comment thread docs/rust-binary-router-library-design.md
Comment thread src/app.rs
@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Aug 11, 2025

@coderabbitai please create a new GitHub issue for the following:

Name the consuming getter into_payload

Follow Rust idioms for consuming accessors. Provide a non-breaking path by adding into_payload(self) and deprecating payload(self).

     #[must_use]
-    pub fn payload(self) -> Vec<u8> { self.payload }
+    pub fn into_payload(self) -> Vec<u8> { self.payload }

Update internal examples and call sites to use into_payload().

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 11, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

I'll create a GitHub issue for this improvement to follow Rust naming conventions for consuming accessors.

@leynos I've created a GitHub issue to track the improvement for renaming the consuming getter method to follow Rust idioms. The issue includes the proposed code change, implementation tasks, and references back to this PR and your comment.


🏁 Script executed:

#!/bin/bash
gh issue create \
  --title "Name the consuming getter \`into_payload\`" \
  --body "Follow Rust idioms for consuming accessors. Provide a non-breaking path by adding \`into_payload(self)\` and deprecating \`payload(self)\`.

## Proposed Change

\`\`\`diff
     #[must_use]
-    pub fn payload(self) -> Vec<u8> { self.payload }
+    pub fn into_payload(self) -> Vec<u8> { self.payload }
\`\`\`

## Tasks

- [ ] Add \`into_payload(self) -> Vec<u8>\` method to \`PacketParts\`
- [ ] Deprecate existing \`payload(self) -> Vec<u8>\` method
- [ ] Update internal examples and call sites to use \`into_payload()\`
- [ ] Ensure backwards compatibility during transition period

## Context

Raised in PR #282: https://github.com/leynos/wireframe/pull/282
Original comment: https://github.com/leynos/wireframe/pull/282#issuecomment-$(gh api repos/leynos/wireframe/pulls/282/comments --jq '.[-1].id')

Requested by: @leynos" \
  --assignee leynos

Length of output: 964


Perfect! I've successfully created GitHub issue #305 for renaming the consuming getter method to follow Rust idioms. The issue includes:

Clear title and description with the proposed code change
Implementation tasks broken down into actionable items
Context and backlinks to PR #282 and your original comment
Assigned to you (@leynos) as requested

You can view the issue at: #305

The issue tracks the transition from payload(self) to into_payload(self) with proper deprecation for backwards compatibility.

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, no comments

Edit Code Review Bot Settings | Greptile

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7dc1a4 and 0cf6188.

📒 Files selected for processing (1)
  • docs/rust-binary-router-library-design.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
docs/**/*.md

📄 CodeRabbit Inference Engine (docs/documentation-style-guide.md)

docs/**/*.md: Use British English based on the Oxford English Dictionary (en-oxendict) for documentation text.
The word "outwith" is acceptable in documentation.
Keep US spelling when used in an API, for example color.
Use the Oxford comma in documentation text.
Treat company names as collective nouns in documentation (e.g., "Lille Industries are expanding").
Write headings in sentence case in documentation.
Use Markdown headings (#, ##, ###, etc.) in order without skipping levels.
Follow markdownlint recommendations for Markdown files.
Provide code blocks and lists using standard Markdown syntax.
Always provide a language identifier for fenced code blocks; use plaintext for non-code text.
Use - as the first level bullet and renumber lists when items change.
Prefer inline links using [text](url) or angle brackets around the URL; avoid reference-style links like [foo][bar].
Ensure blank lines before and after bulleted lists and fenced blocks in Markdown.
Ensure tables have a delimiter line below the header row in Markdown.
Expand any uncommon acronym on first use, for example, Continuous Integration (CI).
Wrap paragraphs at 80 columns in documentation.
Wrap code at 120 columns in documentation.
Do not wrap tables in documentation.
Use sequentially numbered footnotes referenced with [^1] and place definitions at the end of the file.
Where it adds clarity, include Mermaid diagrams in documentation.
When embedding figures, use ![alt text](path/to/image) and provide concise alt text describing the content.
Add a brief description before each Mermaid diagram in documentation for screen readers.

Document examples showing how to deprecate old message versions gracefully

Write the official documentation for the new features. Create separate guides for "Duplex Messaging & Pushes", "Streaming Responses", and "Message Fragmentation". Each guide must include runnable examples and explain the relevant concepts and APIs.

docs/**/*.md: Use docs/ markdown ...

Files:

  • docs/rust-binary-router-library-design.md
docs/**/*.{md,rs}

📄 CodeRabbit Inference Engine (docs/multi-packet-and-streaming-responses-design.md)

docs/**/*.{md,rs}: The official documentation and examples must exclusively use the declarative Response model for handler responses.
The async-stream pattern must be documented as the canonical approach for dynamic stream generation.

Files:

  • docs/rust-binary-router-library-design.md
**/*.md

📄 CodeRabbit Inference Engine (AGENTS.md)

**/*.md: Markdown paragraphs and bullet points must be wrapped at 80 columns
Markdown code blocks must be wrapped at 120 columns
Do not wrap tables and headings in Markdown
Use dashes (-) for list bullets in Markdown
Use GitHub-flavoured Markdown footnotes ([^1])

Files:

  • docs/rust-binary-router-library-design.md

⚙️ CodeRabbit Configuration File

**/*.md: * Avoid 2nd person or 1st person pronouns ("I", "you", "we")

  • Use en-GB-oxendict (-ize / -our) spelling and grammar
  • Headings must not be wrapped.
  • Documents must start with a level 1 heading
  • Headings must correctly increase or decrease by no more than one level at a time
  • Use GitHub-flavoured Markdown style for footnotes and endnotes.
  • Numbered footnotes must be numbered by order of appearance in the document.

Files:

  • docs/rust-binary-router-library-design.md
🔍 MCP Research (1 server)

Deepwiki:

  • "DeepWiki (search result): The project's roadmap mentions "Phase 6: Multi-Packet Streaming Responses" which plans to add a correlation_id to frame headers so multi-packet responses can reuse a request's correlation id; the Connection actor would send each chunk as a Frame that carries that correlation_id. (https://deepwiki.com/search/introduce-packetparts-and-opti_d0b58aa4-c2d4-423f-8d7c-6161102490b1)"
  • "ask_question (leynos/wireframe): The Packet trait overview in project docs describes id(), into_parts(), and from_parts() as the packet decomposition/reassembly interface; into_parts/from_parts are used to extract/construct id and payload bytes for routing and custom Envelope implementations. (leynos/wireframe internal docs via ask_question)"
🔇 Additional comments (2)
docs/rust-binary-router-library-design.md (2)

501-506: Keep sentence case and scope statement — LGTM

The subsection heading and the brief overview follow the documentation style guide and correctly scope the abstraction to Packet, PacketParts, and Envelope.


537-544: Clarify streaming linkage — LGTM and compliant with roadmap

The text explicitly ties correlation_id to multi‑packet streaming and EOS signalling. This complies with the roadmap’s guidance on reusing a request’s correlation identifier across streamed frames.

Comment thread docs/rust-binary-router-library-design.md
Comment thread docs/rust-binary-router-library-design.md
Comment thread docs/rust-binary-router-library-design.md
Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, no comments

Edit Code Review Bot Settings | Greptile

@leynos leynos merged commit 4e0d202 into main Aug 12, 2025
5 checks passed
@leynos leynos deleted the etft5a-codex/address-code-review-comments branch August 12, 2025 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant