• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cameri / nostream / 41332816237
78%
main: 78%

Build:
Build:
LAST BUILD BRANCH: factory/022-settings-ceiling
DEFAULT BRANCH: main
Ran 01 Nov 2026 05:45PM UTC
Jobs 2
Files 267
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

01 Nov 2026 05:42PM UTC coverage: 73.979%. Remained the same
41332816237

push

github

web-flow
refactor(relay): decode the refusal word exhaustively (#1026)

Closes #993.

`Account::refusal()` decoded the refusal word with a wildcard:

```rust
match self.refusal.load(Ordering::SeqCst) {
    QUEUE_FULL => Some(Refusal::QueueFull),
    BUDGET_EXHAUSTED => Some(Refusal::BudgetExhausted),
    _ => None,           // an unknown word reads as "no refusal"
}
```

`Refusal` has two variants, so the wildcard is unreachable *today*. The
defect is what a third cause does: `refuse()` and `close_refused()` are
compiler-forced to handle it, `refusal()` is not, and every reader takes
its `None` as "nothing to do".

**Measured, not argued.** A program carrying the decode verbatim, over
four words:

```
       NO_REFUSAL (0) -> None; is_some()=false
       QUEUE_FULL (1) -> Some(QueueFull); is_some()=true
 BUDGET_EXHAUSTED (2) -> Some(BudgetExhausted); is_some()=true
    A_THIRD_CAUSE (3) -> None; is_some()=false     <-- indistinguishable from no refusal
```

while the same snippet with a third variant added does not compile at
the encode site (`error[E0004]: non-exhaustive patterns`). That
asymmetry is the issue.

## What changed

The refusal word becomes a `Refusal` that names its own "nothing
refused" case:

```rust
#[repr(u8)]
pub enum Refusal {
    None = NO_REFUSAL,              // 0 — the value the first-cause-wins CAS compares
    QueueFull = QUEUE_FULL,         // 1
    BudgetExhausted = BUDGET_EXHAUSTED, // 2
}
```

`Account::refusal()` and `FrameSink::refusal()` return `Refusal` rather
than `Option<Refusal>`; `word()`/`from_word()` both live on the type;
and every reader that decides a cause now has to answer the compiler:

| site | before | after |
|---|---|---|
| `sink.rs` `send`, two latch checks | `== Some(Refusal::QueueFull)` |
`== Refusal::QueueFull` (still an equality test — see below) |
| `relay.rs` connection loop | `if let Some(refusal) = …` | `match` with
`Refusal::None => {}` and `refusal @ (QueueFull \| BudgetExhausted)` |
| `relay.rs` `... (continued)

3588 of 5362 branches covered (66.92%)

Branch coverage included in aggregate %.

7992 of 10291 relevant lines covered (77.66%)

867.55 hits per line

Jobs
ID Job ID Ran Files Coverage
1 Unit - 41332816237.1 01 Nov 2026 05:47PM UTC 267
70.9
GitHub Action Run
2 Integration - 41332816237.2 01 Nov 2026 05:45PM UTC 267
32.54
GitHub Action Run
Source Files on build 41332816237
  • Tree
  • List 267
  • Changed 0
  • Source Changed 0
  • Coverage Changed 0
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #41332816237
  • beaacde6 on github
  • Prev Build on rewrite/main (#41317034116)
  • Next Build on rewrite/main (#41438115701)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc