Skip to content

Tighten public APIs ahead of release: non_exhaustive + builders#1472

Merged
kixelated merged 2 commits into
mainfrom
claude/vibrant-bose-699801
May 23, 2026
Merged

Tighten public APIs ahead of release: non_exhaustive + builders#1472
kixelated merged 2 commits into
mainfrom
claude/vibrant-bose-699801

Conversation

@kixelated
Copy link
Copy Markdown
Collaborator

Summary

Reaction to the breaking changes flagged in the release-plz PR #1467. Marks wire-format and auth types #[non_exhaustive] so additive changes stop counting as breaking, and reshapes a couple of constructors so the breaks land in this release instead of the next several.

Changes

moq-msf

  • Track is now #[non_exhaustive] and gains a Track::new(name, packaging) constructor. External callers (currently just moq-mux) build a track via new + field assignment instead of a struct literal, but future CMSF/MSF optional fields can be added without a major bump.

moq-mux

  • Fmp4::Export::new(broadcast) and Mkv::Export::new(broadcast) now default to CatalogFormat::Hang. Callers that need MSF use the new with_catalog_format(broadcast, format) constructor.
  • moq-cli subscribe updated accordingly; tests collapse to Export::new(consumer) since they were always asking for Hang.

moq-relay

  • AuthToken is now #[non_exhaustive]. All construction already routes through AuthToken::unrestricted() or Auth::verify(), so nothing else moved.
  • Cluster switched to a small builder:
    • Cluster::new(config) — fresh origin, no client, Stats::disabled().
    • .with_client(client) — required when config.connect is non-empty (validated in run() with a clear error).
    • .with_stats(stats) — replaces the no-op default.
  • Cluster.client is now Option<moq_native::Client>.
  • StatsConfig::build(origin) -> Stats encapsulates the config-to-aggregator translation, so the relay's main.rs calls it unconditionally (it returns Stats::disabled() when the config has stats off).

Test plan

  • cargo check -p moq-msf -p moq-mux -p moq-cli -p moq-relay --all-targets
  • cargo test -p moq-msf -p moq-mux -p moq-cli -p moq-relay
  • cargo clippy -p moq-msf -p moq-mux -p moq-cli -p moq-relay --all-targets -- -D warnings

Release plz follow-up

This PR intentionally does not override versions in Cargo.toml. Release-plz will detect the changes here (Track::new is genuinely breaking, Cluster::new arity changed) and propose new bumps:

  • moq-msf will likely go to 0.2.0 since Track::new replaces struct-literal construction; that's accurate.
  • moq-relay will still flag breaking changes (per the existing patch-bump-for-relay policy in #1467).

The intent is that subsequent releases stop tripping the same lints, since the now-#[non_exhaustive] types absorb additive changes.

🤖 Generated with Claude Code

- moq-msf: mark `Track` non_exhaustive and add `Track::new` so future
  CMSF/MSF field additions don't keep breaking the wire-format struct.
- moq-mux: default `Fmp4::Export::new` and `Mkv::Export::new` to the
  `Hang` catalog format; add `with_catalog_format` for callers that need
  MSF (moq-cli's `--catalog` flag).
- moq-relay: mark `AuthToken` non_exhaustive and refactor `Cluster` to
  a builder. `Cluster::new(config)` takes only `ClusterConfig`; attach
  the QUIC client and stats aggregator via `with_client` and
  `with_stats`. `StatsConfig::build(origin) -> Stats` centralizes the
  config-to-aggregator translation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

Review Change Stack

Warning

Review limit reached

@kixelated, we couldn't start this review because you've used your available PR reviews for now.

Your plan currently allows 4 reviews/hour. Refill in 4 minutes and 28 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, 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 trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b77faf0-fffc-4217-a815-92f7934794e1

📥 Commits

Reviewing files that changed from the base of the PR and between aedbb28 and d21102b.

📒 Files selected for processing (1)
  • rs/moq-msf/src/lib.rs

Walkthrough

This PR refactors multiple public APIs to require explicit construction paths and builder-style initialization. The Track struct in moq-msf gains a #[non_exhaustive] marker and public Track::new(...) constructor, with all internal and external Track usage updated accordingly. Container exporters (fMP4 and MKV) simplify their Export::new(...) to accept only broadcast consumer and default to CatalogFormat::Hang, introducing Export::with_catalog_format(...) for explicit format selection. The moq-relay Cluster converts from eager construction to a builder pattern with optional QUIC client and deferred stats attachment via with_client() and with_stats() methods. AuthToken is marked #[non_exhaustive] to reserve space for future context fields. A new StatsConfig::build(origin) method enables deferred stats construction in main.rs, which now builds stats separately and attaches them after creating the cluster.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title "Tighten public APIs ahead of release: non_exhaustive + builders" clearly and concisely summarizes the main changes: marking types as non_exhaustive and refactoring constructors to use builder patterns.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, detailing changes across moq-msf, moq-mux, moq-cli, and moq-relay with clear explanations of the non_exhaustive attributes and builder pattern implementations.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/vibrant-bose-699801
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch claude/vibrant-bose-699801

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

❤️ Share

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

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.

🧹 Nitpick comments (1)
rs/moq-msf/src/lib.rs (1)

32-36: ⚡ Quick win

Update documentation to reflect the new Track::new constructor.

The current documentation suggests external code should "start from a previously produced Track" or "use struct update syntax", but the newly added Track::new constructor (lines 113-141) provides a direct fresh construction path. The documentation should mention Track::new(...) as the primary construction method for external callers, followed by field assignment.

📝 Suggested documentation update
 /// A single track in the MSF catalog.
 ///
 /// Marked `#[non_exhaustive]` because the CMSF/MSF drafts continue to grow
 /// optional fields. External constructors should start from a previously
-/// produced `Track` (e.g. from `Catalog::from_str`) or use struct update
-/// syntax against one.
+/// produced `Track` (e.g. from `Catalog::from_str`), or use [`Track::new`]
+/// to construct a fresh track and set fields via assignment.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rs/moq-msf/src/lib.rs` around lines 32 - 36, Update the doc comment that
currently advises consumers to "start from a previously produced `Track` or use
struct update syntax" to instead call out the new public constructor
`Track::new(...)` as the recommended primary construction path for external
callers, then mention that callers can further adjust optional fields via struct
update syntax or field assignment; update the sentence near the
`#[non_exhaustive]` note to mention `Track::new` and keep `Catalog::from_str` as
an alternative source when appropriate.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@rs/moq-msf/src/lib.rs`:
- Around line 32-36: Update the doc comment that currently advises consumers to
"start from a previously produced `Track` or use struct update syntax" to
instead call out the new public constructor `Track::new(...)` as the recommended
primary construction path for external callers, then mention that callers can
further adjust optional fields via struct update syntax or field assignment;
update the sentence near the `#[non_exhaustive]` note to mention `Track::new`
and keep `Catalog::from_str` as an alternative source when appropriate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab5f5061-809e-4654-badf-42a46e9f6dff

📥 Commits

Reviewing files that changed from the base of the PR and between 88b9225 and aedbb28.

📒 Files selected for processing (12)
  • rs/moq-cli/src/subscribe.rs
  • rs/moq-msf/src/lib.rs
  • rs/moq-mux/src/catalog/hang/producer.rs
  • rs/moq-mux/src/catalog/msf/consumer.rs
  • rs/moq-mux/src/container/fmp4/export.rs
  • rs/moq-mux/src/container/fmp4/export_test.rs
  • rs/moq-mux/src/container/mkv/export.rs
  • rs/moq-mux/src/container/mkv/export_test.rs
  • rs/moq-relay/src/auth.rs
  • rs/moq-relay/src/cluster.rs
  • rs/moq-relay/src/main.rs
  • rs/moq-relay/src/stats.rs

Struct update syntax (`..base`) is also blocked by `#[non_exhaustive]`
outside the defining crate, so the previous doc was misleading. Point
external callers at `Track::new` + field assignment instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kixelated kixelated enabled auto-merge (squash) May 23, 2026 22:19
@kixelated kixelated merged commit 9f780fa into main May 23, 2026
1 check passed
@kixelated kixelated deleted the claude/vibrant-bose-699801 branch May 23, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant