We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Generics and Traits step 9 of 24
Convert temperatures with From and Into
Replace the starter's direct Into implementation with a From
implementation, keeping the supplied convert function unchanged.
pub struct Celsius(pub f64);
pub struct Fahrenheit(pub f64);
impl From<Celsius> for Fahrenheit { /* implement from */ }
pub fn convert(temps: Vec<f64>) -> Vec<f64>
Use C * 9.0 / 5.0 + 32.0 to convert Celsius to Fahrenheit. Return one
result per input, preserving order and duplicates. Empty input returns an
empty vector. Do not round the results to a fixed number of decimal places.
| Input | Output |
|---|---|
[0.0, 100.0] |
[32.0, 212.0] |
[-40.0] |
[-40.0] |
[37.0, 20.5] |
[98.6, 68.9] |
[] |
[] |
Inputs are finite f64 values whose intermediate multiplication by 9 and
final result remain finite. This exercise applies the formula even below
absolute zero; it does not validate physical temperatures. Floating-point
arithmetic may round internally, so infallible does not mean exact decimal
arithmetic.
Why implement From?
From<Celsius> for Fahrenheit defines a conversion on the destination type.
Its method is fn from(c: Celsius) -> Self.
The standard library provides Into<U> for T whenever U: From<T>. This
blanket implementation means your From implementation also enables
Celsius(t).into(). The destination type in let f: Fahrenheit = ... tells
Rust which conversion is wanted.
The starter's direct Into implementation computes the right values, but
Clippy's from_over_into lint rejects it under warnings-as-errors. Replace
that implementation, rather than adding From beside it. Keep the formula
and the existing .into() call in convert.
Two types for two units
Celsius and Fahrenheit are newtypes: distinct types wrapping the same
underlying numeric type. A function expecting Fahrenheit will not silently
accept Celsius. Conversion must be requested explicitly, for example with
Fahrenheit::from(c) or a type-directed c.into().
These wrappers introduce no heap allocation themselves. Their default Rust
representation does not promise an ABI identical to f64; #[repr(transparent)]
is the representation attribute used when that guarantee is needed. No
representation change is required for this exercise.
Avoid conflicting implementations
Adding both From<Celsius> for Fahrenheit and Into<Fahrenheit> for Celsius
produces E0119: the explicit Into overlaps the blanket implementation.
Similarly, a custom From<Celsius> for Celsius conflicts with the standard
identity conversion, From<T> for T.
Your local wrapper types also let you implement standard traits for them.
An implementation such as From<Vec<u8>> for String is rejected with E0117
because the trait and both involved types belong to other crates. Wrapping
a type locally is useful when you need your own conversion behavior.
From implementations and Into bounds
Prefer implementing From when defining a conversion. An API accepting
T: Into<Fahrenheit> can then accept any T with the corresponding From
implementation, as well as types that implement Into directly. The reverse
implication does not hold: a direct Into implementation does not create
a From implementation.
For ordinary Result error propagation, ? uses a From conversion when
the source and destination error types differ. That is a separate use of
the trait; these temperature wrappers are not error types. If a conversion
can reject its input, use a fallible interface such as TryFrom rather than
hiding that failure inside a From implementation.
Your solution must compile, preserve convert, match the outputs 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.