match expressions — compile-time exhaustive checking
Absolutely. match expressions with compile-time exhaustive checking are one of Rust’s most powerful features for building reliable, bug-resistant code—especially critical in systems like MSP agents, compliance tools, or aviation-adjacent software where missing a case can mean failure or security risk.
Let’s break it down clearly.
🔍 What Is a match Expression?
A match in Rust is like a super-powered switch that:
-
Compares a value against patterns (not just constants)
-
Extracts data while matching
-
And most importantly: requires you to handle every possible case
If you forget a case, your code will not compile.
✅ Example 1: Exhaustive Handling of an Enum
Define a system status enum (common in diagnostics tools):
#[derive(Debug)]
enum SystemStatus {
Healthy,
Degraded { reason: String },
Offline,
Maintenance,
}
Now match on it:
fn handle_status(status: SystemStatus) {
match status {
SystemStatus::Healthy => println!("✅ All systems operational"),
SystemStatus::Degraded { reason } => println!("⚠️ Degraded: {}", reason),
SystemStatus::Offline => println!("🛑 System offline"),
// SystemStatus::Maintenance => ... // ❌ COMPILE ERROR if missing!
}
}
🔥 If you comment out the
Maintenancearm, Rust says:error[E0004]: non-exhaustive patterns: `Maintenance` not covered
This forces completeness—no accidental logic gaps.
✅ Example 2: Real-World — MSP Compliance Check Result
Imagine a compliance scanner for ISO labs (like your clients):
#[derive(Debug)]
enum ComplianceResult {
Pass,
Fail { violation: String, severity: u8 },
Inconclusive { reason: String },
Exempt { justification: String },
}
fn report_compliance(result: ComplianceResult) -> String {
match result {
ComplianceResult::Pass => "✅ PASS: All checks satisfied".into(),
ComplianceResult::Fail { violation, severity } => {
format!("❌ FAIL (Severity {}): {}", severity, violation)
},
ComplianceResult::Inconclusive { reason } => {
format!("❓ INCONCLUSIVE: {}", reason)
},
ComplianceResult::Exempt { justification } => {
format!("➖ EXEMPT: {}", justification)
}
// Try removing any arm → won't compile!
}
}
💼 Why this matters for your business:
You never miss a compliance state in reporting.
Auditors love explicit handling of all outcomes.
No silent "default" that hides critical failures.
🧩 match Can Also Deconstruct Complex Data
You can match on:
-
Tuples:
let http_status = (404, "Not Found"); match http_status { (200, _) => println!("OK"), (404, msg) => println!("Not found: {}", msg), (code, _) => println!("Other error: {}", code), } -
Option/Result (instead of
if let):match get_client_id() { Some(id) => log_audit_event(id), None => return Err("Client ID required for secure report".into()), } -
Structs (with field extraction):
struct Device { model: String, firmware: u32 } match device { Device { firmware: 0..=100, .. } => println!("⚠️ Outdated firmware"), Device { model, firmware: _ } => println!("✅ {} is up to date", model), }
🚫 What Rust Prevents
| Mistake in Other Languages | Rust’s Fix |
|---|---|
switch without default → undefined behavior |
Exhaustiveness check → must cover all cases |
if-else if chain misses a state |
match won’t compile if incomplete |
Silent fallback (else) hides new enum variants |
Add a new variant → all match sites break → you must update them |
🔁 This is called "making illegal states unrepresentable"—a core reliability principle.
🛠️ Practical Tip: Use #[non_exhaustive] Carefully
If you’re building a library (e.g., an SDK for clients), you can mark an enum as #[non_exhaustive] to allow future additions without breaking callers:
#[non_exhaustive]
enum ApiError {
Timeout,
AuthFailed,
}
But in your own application code, avoid it—you want exhaustiveness for safety.
✅ Summary
Rust’s
matchdoesn’t just route logic—it enforces correctness.
By requiring every possible case to be handled, it eliminates an entire class of logic bugs that cause crashes, security gaps, or compliance failures.
This is not possible in Go (no sum types), Python (dynamic), or C (manual switches). Even TypeScript’s switch can’t guarantee exhaustiveness without extra tooling.
💼 Why This Matters for You
-
Your MSP contracts promise reliability →
matchensures no state is overlooked. -
Your seminars for labs/MROs can highlight:
“Our tools are built in Rust—so if it compiles, it handles every scenario.”
-
You reduce support tickets caused by “unhandled edge cases.”