We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Shape Your Data: Structs, Enums, Pattern Matching step 17 of 26
Count enum variants with matches!
Complete count_shapes using matches! predicates. Keep the supplied Shape
enum and parser, replace the starter's boolean match, and fill in the three
missing counts.
pub fn count_shapes(descriptors: Vec<String>) -> Vec<u64>
Return exactly four counts in this order:
| Position | Count | Include |
|---|---|---|
| 0 | round | Every Circle |
| 1 | straight | Every Square or Rect |
| 2 | big | Circles whose radius is strictly greater than 10.0 |
| 3 | unknown | Every Unknown |
These categories overlap: a big circle also contributes to round. Count each
descriptor independently, including duplicates. Empty input returns
[0, 0, 0, 0].
For ["circle 5", "circle 20", "square 3", "rect 2 3", "blob"], return
[2, 2, 1, 1].
Follow the supplied parser
The parser splits on whitespace and accepts exactly these token sequences:
circlefollowed by onef64value.squarefollowed by onef64value.rectfollowed by twof64values.
Names are lowercase and case-sensitive. Extra or missing tokens, unknown names
and failed numeric conversions produce Unknown. Repeated spaces and leading
or trailing whitespace are accepted.
This parser classifies syntax; it does not validate physical dimensions.
Negative values and scientific notation are accepted. Rust's f64 parser
also accepts NaN and infinity: circle NaN counts as round but not big,
while circle inf counts as both. Keep this behavior rather than adding
geometric validation.
Turn a pattern into a boolean
Use matches!(value, pattern) when you only need to know whether a pattern
matches. For example:
matches!(shape, Shape::Circle(_))
It has the same result as a match whose matching arm returns true and
fallback arm returns false. The starter uses that longer form for round;
Clippy's match_like_matches_macro flags it under this exercise's warnings
gate.
An or-pattern handles the two straight-sided variants:
matches!(shape, Shape::Square(_) | Shape::Rect(_, _))
A guard adds a condition after a successful pattern match. Here shape is a
borrowed shape, so the radius binding is a reference:
matches!(shape, Shape::Circle(r) if *r > 10.0)
The boundary is strict: radius 10.0 is not big, and 10.5 is.
Understand the references in filter
shapes.iter() yields &Shape. filter borrows each iterator item when it
calls its predicate, so the closure argument s has type &&Shape:
shapes.iter().filter(|s| matches!(s, Shape::Circle(_))).count()
Match ergonomics let these variant patterns work through the references.
In the guarded pattern, r has type &f64, so dereference it for the
comparison. Each filter examines a borrowed value; it does not consume the
shapes vector.
Bindings stay inside the match
matches! can bind r for use in its guard. That binding is not available
afterward: the macro returns only a bool. Use if let or match when you
need to extract a payload and do more work with it.
The parser's map_or(Shape::Unknown, Shape::Circle) uses the tuple variant
constructor as a function: a successful numeric parse becomes Circle(value).
You do not need to change that parser to complete the counting predicates.
The solution must compile, return the expected counts and pass
clippy -D warnings.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.