Pattern Matching
Level: intro (score: 1)
π These intro exercises are prep for our
Rust Intro Cohort Program.
π― Rust’s match goes far beyond switch-style branching. This exercise drills the essentials you’ll use in the parser: destructuring, multiple patterns, ranges, guards, and the catchβall _.
β Your task
Implement these three functions in src/main.rs:
-
classify_char(c: char) -> &'static str- Return
"digit"for'0'..='9' "alpha"for'a'..='z' | 'A'..='Z' | '_'"op"for one of+ - * / ="ws"for space, tab, or newline"other"otherwise
- Return
-
sum_positive_pairs(input: &[(i32, i32)]) -> i32- Sum
x + yonly for pairs where both are> 0using tuple destructuring with a guard. Skip others.
- Sum
-
Define the enum:
#[derive(Debug, PartialEq, Eq)]
pub enum Message {
Ping,
Echo(String),
Move { x: i32, y: i32 },
Quit,
}
Implement route(msg: Message) -> String using pattern matching:
Ping→"pong"Echo(s)→ returnsif non-empty, else"silence"(use a guard)Move { x, y }→- if
x == 0 && y == 0→"noop" - else format
"move:{x},{y}"
- if
Quit→"bye"- use
_only if you must (exhaustive matches are preferred)
π‘ Hints
- Ranges:
'0'..='9','a'..='z' - Multiple patterns:
' ' | ' ' | ' ' - Guards:
SomeBinding if condition => ... - Destructure tuples:
for &(x, y) in input { ... }
Example tests:
assert_eq!(classify_char('8'), "digit");
assert_eq!(classify_char('_'), "alpha");
assert_eq!(classify_char('+'), "op");
assert_eq!(classify_char('\n'), "ws");
assert_eq!(classify_char('?'), "other");
assert_eq!(sum_positive_pairs(&[(1,2), (-1,3), (4,0)]), 3);
use Message::*;
assert_eq!(route(Ping), "pong");
assert_eq!(route(Echo("hi".into())), "hi");
assert_eq!(route(Echo("".into())), "silence");
assert_eq!(route(Move { x: 0, y: 0 }), "noop");
assert_eq!(route(Move { x: 2, y: -1 }), "move:2,-1");
assert_eq!(route(Quit), "bye");
#[derive(Debug, PartialEq, Eq)]
pub enum Message {
Ping,
Echo(String),
Move { x: i32, y: i32 },
Quit,
}
pub fn classify_char(c: char) -> &'static str {
// TODO: use ranges and multiple patterns to classify
"other"
}
pub fn sum_positive_pairs(input: &[(i32, i32)]) -> i32 {
// TODO: destructure tuple and use a guard to sum only > 0 pairs
0
}
pub fn route(msg: Message) -> String {
// TODO: match on Message, using guards for Echo non-empty and Move (0,0)
String::new()
}
#[cfg(test)]
mod tests {
use super::*;
use Message::*;
#[test]
fn test_classify_char() {
assert_eq!(classify_char('8'), "digit");
assert_eq!(classify_char('_'), "alpha");
assert_eq!(classify_char('+'), "op");
assert_eq!(classify_char('\n'), "ws");
assert_eq!(classify_char('?'), "other");
}
#[test]
fn test_sum_positive_pairs() {
assert_eq!(sum_positive_pairs(&[]), 0);
assert_eq!(sum_positive_pairs(&[(1,2), (-1,3), (4,0)]), 3);
assert_eq!(sum_positive_pairs(&[(2,2), (3,3)]), 10);
}
#[test]
fn test_route() {
assert_eq!(route(Ping), "pong");
assert_eq!(route(Echo("hi".into())), "hi");
assert_eq!(route(Echo("".into())), "silence");
assert_eq!(route(Move { x: 0, y: 0 }), "noop");
assert_eq!(route(Move { x: 2, y: -1 }), "move:2,-1");
assert_eq!(route(Quit), "bye");
}
}