1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Tests for [`super`] — the word a log line uses for what happened.
//!
//! Split out via `#[path]` so `outcome.rs` stays inside the file-size
//! budget.
use Outcome;
/// Every variant, listed by hand because nothing derives it.
///
/// The `match` in `as_str` is exhaustive, so the *compiler* already refuses
/// a variant with no arm there. What no compiler can check is whether this
/// list is complete — so the check is made a compile error instead, by
/// `a_new_variant_cannot_be_added_without_visiting_this_file` below.
const EVERY: & = &;
/// Two outcomes that log the same word are one outcome, as far as anyone
/// reading the log is concerned.
///
/// This is the copy-paste arm: `Self::TimedOut => "bad_request"` compiles,
/// passes every other test in this crate, and silently makes a timeout
/// indistinguishable from a malformed head in the one place an operator
/// would look.
/// The negative control for the test above, which it needs more than most:
/// a broken `as_str` returning `""` for everything would fail that one, but
/// a broken `EVERY` listing a single variant six times would *pass* it.
/// Adding a variant to [`Outcome`] must stop this file compiling.
///
/// The match below is exhaustive with no wildcard arm, so a new variant is
/// a compile error *here* — which is the event that sends whoever added it
/// to `EVERY` above. That is the only mechanism available: nothing derives
/// the variant list, so no assertion executed at run time can notice a
/// variant missing from a hand-written const.
///
/// A length assertion cannot do this job, and the one that used to sit
/// here was worse than useless. `assert_eq!(EVERY.len(), 6)` is a property
/// of the literal rather than of the enum: it stayed silent in exactly the
/// case its message described — a variant added, `EVERY` left stale — and
/// fired only on somebody correctly extending the list. It alarmed on the
/// right state and passed on the wrong one.
/// An operator greps these, so they are a lower-case, underscore-separated
/// vocabulary rather than whatever `Debug` renders.
///
/// `Debug` would give `BadGateway`, and the difference is not cosmetic: it
/// is the difference between one `grep bad_gateway` finding both this field
/// and the refusal body's `"code"`, and finding neither reliably.