We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors Are Values step 8 of 24
Result combinators and map_err
Parse each input as an i32 and return its doubled value as a string. When
parsing fails, return bad input: followed by the original input. Keep the
input order and produce one output for every input, including failures.
pub fn parse_all(raw: Vec<String>) -> Vec<String>
| Input | Output |
|---|---|
"20" |
"40" |
" 5 " |
"10" |
"12x" |
"bad input: 12x" |
" x " |
"bad input: x " |
"" |
"bad input: " |
"2147483647" |
"4294967294" |
An empty input vector produces an empty output vector. Error messages contain no added quotation marks or newline.
Trim for parsing, preserve the original for errors
Call trim() before parsing. Integer parsing does not remove surrounding
whitespace itself. Use the original string in the error message so spaces
and other characters are preserved.
The trimmed input must be a decimal integer in the i32 range. A leading
plus or minus is accepted; decimal points, underscores and out-of-range
values fail. For example, both "3.5" and "9999999999" produce error messages.
A successful parse does not guarantee that doubling fits in i32. Convert
the parsed value to i64 before multiplying by two. Every doubled i32
value fits in i64; parsing directly as i64 would incorrectly accept
inputs outside the requested range.
Transform success and failure separately
Parsing produces Result<i32, ParseIntError>. map transforms a successful
value; map_err transforms an error. Each leaves the other variant alone.
s.trim().parse::<i32>()
.map_err(|_| format!("bad input: {s}"))
This expression has type Result<i32, String>. The closure replaces the
parse error with the exercise's message and captures s to include the input.
A parse error describes the failure but does not store the original input.
Use map to turn a successful number into its doubled decimal string.
Once both variants contain a String, unwrap_or_else(|error| error) can
return the error string on failure and the success string otherwise.
Unlike unwrap(), this does not panic simply because the result is Err.
What needs fixing in the starter
The starter converts the parse result to an Option, then returns only
"bad input" on failure. That loses the required input text. The original
string is still available, so discarding ParseIntError alone does not make
it impossible to construct the message.
Clippy's manual_ok_err lint also flags the match that converts Ok to
Some and Err to None. Replacing it with .ok() addresses that lint,
but does not fix the missing text or the arithmetic overflow.
Choosing what an error should retain
This exercise intentionally returns the same message format for every parse failure. Other APIs may need to distinguish invalid digits from out-of-range values, or retain the original error as a cause. Choose that representation from the caller's needs; a user-facing message does not require discarding the underlying error everywhere else in a program.
For later exercises, and_then chains an operation that returns another
Result, while or_else tries recovery after an error. An ordinary match
is also useful when the branches need several steps.
Passing requires compilation, correct outputs and Clippy with warnings treated as errors.
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.