`From` tells Rust how to convert a value of one type into another. Implement `From<T> for U` and define `from(value: T) -> U`; callers can then write `U::from(value)`. Implementing `From` also normally makes `.into()` available for the reverse calling style. Use `TryFrom` instead when conversion may fail. section 5.5 section 9.9.3 section 5.8
A compact Q7 fixed-point value stores its bits in an `i8`. Converting an `f64` to Q7 scales the value and clamps inputs outside the supported range; converting back scales the stored integer down. Separate implementations handle each direction. Conversion need not preserve exact precision: representations of time can also lose accuracy when converted. section 5.5 section 9.9.3
Listing 5.12 Converting from f64 to Q7
impl From<f64> for Q7 {
fn from (n: f64) -> Self {
// assert!(n >= -1.0);
// assert!(n <= 1.0);
if n >= 1.0 { #1
Q7(127)
} else if n <= -1.0 { #1
Q7(-128)
} else {
Q7((n * 128.0) as i8)
}
}
}
impl From<Q7> for f64 {
fn from(n: Q7) -> f64 {
(n.0 as f64) * 2_f64.powf(-7.0) #2
}
}
Compare the two `impl From` blocks: the source and destination types switch places, and each `from` method performs its own calculation. section 5.5
`From` is also useful when a function can encounter several error types. Define a wrapper error enum with a variant for each upstream error, then implement `From` for each one. A function returning that wrapper can use `?` on both file and address-parsing operations without writing `map_err()` at every call. section 8.5.2 section 8.11
impl From<io::Error> for UpstreamError {
fn from(error: io::Error) -> Self {
UpstreamError::IO(error)
}
}
impl From<net::AddrParseError> for UpstreamError {
fn from(error: net::AddrParseError) -> Self {
UpstreamError::Parsing(error)
}
}
Each implementation puts one upstream error into its matching wrapper variant. section 8.5.2



