We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors Are Values step 15 of 24
From impls: the machinery behind ?
Parse a count and a value, using ? to convert each parser's error into your
application error. Use bare ? on both parses, without map_err.
pub enum AppError { Int(ParseIntError), Float(ParseFloatError), Empty }
pub fn parse_record(line: String) -> Result<(i32, f64), AppError>
Parsing rules
Trim the line with str::trim. If nothing remains, return AppError::Empty.
Otherwise split at the first comma, trim each field, and parse the left
field as i32 before parsing the right field as f64.
With no comma, use the whole trimmed line as the left field and an empty right field. A valid count then produces a float error; an invalid count fails first. Additional commas stay in the right field and cause a float parse error. This format has no quoting or escaping rules.
"42,3.5" returns Ok((42, 3.5)), and " 7 , -2.25 " returns
Ok((7, -2.25)). "x,y" returns an integer error. "," is an empty
integer field, not an empty record.
Use the standard parsers' syntax: the count accepts decimal digits with an
optional sign and must fit in i32. The float parser also accepts exponent
notation and non-finite values. Do not add a finite-value check. The harness
reports non-finite successful values as "NaN", "Infinity" or "-Infinity"
because JSON numbers cannot represent them. Finite values remain numbers.
Keep the message and cause separate
| Variant | Exact Display text | source() |
|---|---|---|
Int(e) |
count field is not an integer |
The contained ParseIntError |
Float(e) |
value field is not a number |
The contained ParseFloatError |
Empty |
record is empty |
None |
Keep the supplied Display implementation. Implement Error::source so callers
can inspect the wrapped error instead of losing access to it through the
error-chain interface. The default source() returns None; it does not
delete the error stored in the enum.
The harness renders the source using its own Display implementation. Do not hard-code the standard library's error messages or append them to AppError's Display text. For example, an invalid digit and an out-of-range integer share the same application message but retain different underlying causes.
Add two From implementations
Implement From<ParseIntError> for AppError by returning AppError::Int(e),
and From<ParseFloatError> for AppError by returning AppError::Float(e).
Neither conversion parses anything or introduces a new failure.
In this Result-returning function, a successful parse()? yields its value.
A failed parse returns early with its error converted through From into
AppError. Without the corresponding conversion, the compiler reports E0277.
Annotate the local bindings as i32 and f64 so each parse has a known target.
The starter's generic impl<E: Error> From<E> for AppError instead produces
E0119. Since AppError implements Error, that implementation also covers
E = AppError, overlapping the standard identity conversion From<T> for T.
Replace it with the two concrete implementations rather than adding to it.
What the source lifetime means
source returns Option<&(dyn Error + 'static)>. The reference is borrowed
from self; it need not live forever. The 'static bound applies to the
underlying error type, excluding non-static borrowed data. An error can still
contain a reference to static data. Both standard parse-error types fit here.
From suits this context-free wrapping. When a conversion needs a filename,
field name or other information available only at one call site, an explicit
conversion such as map_err may be more appropriate. Here the two field
roles are already represented by the two error variants.
Your solution must compile, preserve the required messages and sources,
use ? for both parses and pass 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.