Enums, Option & Pattern Matching

Enums that carry data, Option instead of null, and match / if let to take them apart.

Rust enums are far more powerful than C's: each variant can hold different data. Together with match they model 'one of several kinds of thing' precisely — a CAN frame is a data frame, a remote frame, an error or an overload, never a mixture. Option<T> uses the same idea to replace null pointers.

Frames and optional values

Frame::Data { id, bytes } has named fields; Frame::Error(String) holds one value; Frame::Overload holds nothing.

match destructures each variant; the guard if bytes.is_empty() picks out empty data frames first.

find_sensor returns Option<&str>: Some(name) or None. The caller cannot use the name without handling None.

if let handles just one pattern; unwrap_or and map handle common cases without a full match.

Why Option beats null

let name = find_sensor(id).unwrap(); // in production code match find_sensor(id) { Some(n) =>..., None =>... } // or ? / unwrap_or unwrap panics on None. Keep it for tests and prototypes; handle the None case in real code.

What does Option<T> replace, and why is it safer?

Nullable pointers/references. The type system distinguishes 'maybe a T' from 'definitely a T', so code must handle None explicitly before using the value.

What happens if a match on an enum misses a variant?

It does not compile (error E0004, non-exhaustive patterns), unless a _ arm covers the rest.