We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Shape Your Data: Structs, Enums, Pattern Matching step 11 of 26
Destructuring structs and nested patterns
Summarize order records using nested struct and enum patterns. Each record
contains exactly five |-separated fields:
id|name|tier|status|payload
pub fn summarise(records: Vec<String>) -> Vec<String>
Return one summary per record, preserving input order. Empty input returns an empty vector.
1|Ada|gold|pending| -> 1 Ada priority waiting
2|Bob|basic|pending| -> 2 Bob waiting
3|Cy|gold|shipped|DHL -> 3 Cy via DHL
4|Dee|basic|cancelled|fraud -> 4 Dee cancelled (fraud)
5|Eve|basic|lost| -> malformed
Keep the supplied parser. It applies these rules:
- The ID must parse as a
u32. Output uses its numeric value, so leading zeroes are not retained. - Only the exact tier
goldis special. Every other tier is basic. - Status must be exactly
pending,shipped, orcancelled. - Pending orders ignore the payload. Shipped orders use it as the carrier; cancelled orders use it as the reason.
- Fields are not trimmed. Empty names and payloads are accepted.
Additional separators, missing fields, invalid IDs, and unknown statuses
produce
malformed.
Repair summarise_one using one match with nested patterns. For this
exercise, avoid field access, if, or another match inside that function.
The supplied parser and outer summarise function can retain their matches.
This is a practice constraint; output tests alone do not enforce it.
Match structure and values together
A pattern can check an enum variant while binding nearby fields.
The gold-pending arm binds the ID and customer name while requiring
Tier::Gold and Status::Pending.
Put that specific arm before the general pending arm. Match arms are tried in order, so the general arm would otherwise consume gold orders too.
Field access is also normal Rust. Nested patterns are useful here because each branch depends on several parts of the record's structure.
Name fields or ignore the remainder
A struct pattern must account for all its fields. In the shipped arm,
Customer { name } omits tier and produces E0027. Use
Customer { name, .. } when the tier does not affect that summary.
_ ignores one matched value, as in tier: _. The rest pattern
.. ignores the fields not otherwise named. Each individual struct pattern
may have its own rest pattern, including a nested struct pattern.
This complete example shows both forms:
struct Customer {
name: String,
tier: u8,
}
fn main() {
let customer = Customer { name: String::from("Ada"), tier: 1 };
let Customer { name, .. } = &customer;
assert_eq!(name, "Ada");
let Customer { name: _, tier } = customer;
assert_eq!(tier, 1);
}
The first pattern borrows the name. The second ignores the name and copies the numeric tier.
Borrowing through a pattern
summarise_one receives &Order. Matching it with a struct pattern
automatically borrows the bound fields, so name is &String and
id is &u32. This behavior is called match ergonomics; it predates
Rust 2024. format! can display those references directly.
Moving a String out through a shared reference would be rejected.
Destructuring an owned struct can move selected fields, but does not
necessarily make all other fields unusable: unmoved fields can remain
accessible. Here, matching by reference leaves the order available.
Use let for a pattern that always matches and match when selecting
among alternatives. This exercise needs alternatives for order status and
the special gold-pending case.
A passing submission must compile, pass the tests, and pass
clippy -D warnings.
See the Rust pattern reference for struct, wildcard, rest, and reference binding rules.
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.