feat(client,server)!: typed CapacityKind in place of the string tag - #151
Merged
Conversation
zheylmun
approved these changes
Aug 21, 2026
JustinKovacich
force-pushed
the
feat/error-surface-and-caps
branch
from
August 21, 2026 13:35
ecd4697 to
ecb337f
Compare
JustinKovacich
force-pushed
the
feat/typed-capacity-kind
branch
from
August 21, 2026 13:35
713039e to
45d2a14
Compare
…acityKind Closes #146. `client::Error::Capacity` and `server::Error::Capacity` carried a `snake_case` string tag, and the docs told the reader to grep the crate for it to find the governing constant. A consumer wanting to tell "the service registry is full" from "the UDP buffer overflowed" had to compare text against a tag set the type system never mentioned — which fails silently, at runtime, and produces a wrong classification rather than an error when a tag is reworded. The five documented tags become `CapacityKind` variants, each carrying the documentation that used to sit in a bulleted list on the variant. The kind is shared between client and server rather than split in two, so capacity exhaustion is handled the same way whichever layer reports it; the server currently produces only `UdpBuffer`, and `#[non_exhaustive]` keeps that asymmetry from being a problem as it grows others. `Display` output is unchanged. `CapacityKind::as_str` returns the exact pre-0.11.0 literals and a test pins each one, so anything reading the rendered error keeps working while it migrates. `reject_with_capacity`'s `structure_name` parameter is typed rather than removed, even though every caller passes `RequestQueue` today — the parameter exists so the rejection path can name a different structure later. Notes: The `Display` test formats through `core::fmt::Write` into a fixed buffer rather than `to_string()`, so it runs under `--no-default-features` where there is no allocator. `capacity` is compiled unconditionally while `client` and `server` are feature-gated, so its module docs reference those error types in prose rather than as intra-doc links — linking them fails the single-feature doc builds. The doc lane caught it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0.11.0 was tagged and released while this branch was open, so the changelog entry written for it now sits under a shipped section and the `Cargo.toml` version it assumed is taken. Move the `CapacityKind` entry into a new `## [0.12.0]` section and bump `version` to 0.12.0 — the same convention 0.10.0 and 0.11.0 used, where the version rides in the PR so `cargo-semver-checks` compares against the version the break actually lands as. `simple-someip-embassy-net` pins the parent by version (`"0.11"`), so it moves too or the workspace stops resolving. The 0.11.0 preamble is restored to its released wording, and the three "pre-0.11.0" references — the `as_str` docs, the `Capacity` variant docs, and the changelog line about the pinned literals — become "0.12.0", since those strings did ship in 0.11.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
JustinKovacich
force-pushed
the
feat/typed-capacity-kind
branch
from
August 24, 2026 14:22
45d2a14 to
ae35a63
Compare
`tests/bare_metal_e2e.rs` matches on `Capacity(CapacityKind::UdpBuffer)` in five places but never imported the type, so the harness failed to compile with five E0433s. The gap survived because that binary only builds under the alloc + `bare_metal` feature set the coverage job selects; the default-feature and per-feature lanes gate it out entirely, and the branch had no CI run of its own before now. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (79.09%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. @@ Coverage Diff @@
## main #151 +/- ##
==========================================
+ Coverage 81.25% 81.30% +0.04%
==========================================
Files 46 47 +1
Lines 15470 15514 +44
==========================================
+ Hits 12570 12613 +43
- Misses 2900 2901 +1
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #146.
Stacked on #150 — merge order is #150 → this. The base is
feat/error-surface-and-caps, notmain, because both touchclient/error.rsandCapacityKindis itself#[non_exhaustive], which #150 establishes.What
client::Error::Capacityandserver::Error::Capacitycarried asnake_casestring tag, with docs instructing the reader to grep the crate for it to find the governing constant. The five documented tags becomeCapacityKindvariants, each carrying the documentation that used to live in a bulleted list on the variant — the information moves from prose into the type.Decisions worth reviewing
One shared kind, not one per error type. The server only produces
UdpBuffertoday, so a server-specific enum would be smaller and tighter. I went the other way: a consumer handling capacity exhaustion should not learn two vocabularies for one condition, and#[non_exhaustive]means the asymmetry costs nothing as the server grows others. The module doc states this explicitly so it reads as a decision rather than an oversight.Displayis unchanged, and pinned.CapacityKind::as_strreturns the exact pre-0.11.0 literals, and a test asserts each one against its literal. Anything reading the rendered error keeps working while it migrates off text-matching — which is the practice this change exists to let consumers stop.reject_with_capacitykeeps its parameter. Every caller passesRequestQueuetoday, so the parameter could have been dropped. It is typed instead: it exists so that rejection path can name a different structure later, and collapsing it would have to be undone.Two things the build caught
The
Displaytest cannot useto_string().capacityis compiled unconditionally, so the test runs under--no-default-featureswhere there is no allocator. It formats throughcore::fmt::Writeinto a fixed buffer instead.Intra-doc links into
client/serverdo not resolve fromcapacity. Same trap as #150: this module is ungated, those are behind features, so linking their error types fails the single-feature doc builds. They are prose in the module doc, with a comment saying why; the one link that is safe (crate::CapacityKind, ungated) is fully qualified.This is the second time in this batch that a plausible-looking doc link silently only worked in one configuration. Unlike #145 the doc lane does catch it — worth keeping that lane in CI.
Verification
cargo clippy -- -D warnings -D clippy::pedanticon all five lanes CI runs: alloc/host workspace,--no-default-features, and the threebare_metalcombinations.cargo test --no-default-features— 253 lib tests (two new), all green.cargo test --features client,bare_metal --test no_alloc_witnessgreen.cargo doc --no-depswithRUSTDOCFLAGS=-D warningsforclient,server,bare_metal, and the alloc set.cargo fmt --all -- --checkclean.grep -rn 'Capacity("' src/ tests/ examples/returns nothing — no string tag survives.