Rust does not automatically convert one numeric type to another, even when both hold integers. If two values have different types, you must make the conversion explicit before comparing them. A type cast uses `as`, as in `b as i32`. section 2.3.1 section 2.3.3
Make a comparison compile
With `let a: i32 = 10;` and `let b: u16 = 100;`, `a < b` does not compile. Write `a < (b as i32)` to convert `b` for the comparison. Casting the smaller type to a larger one is generally safer than converting in the other direction. section 2.3.3
A cast is not a guarantee that the original value will be preserved: `300_i32 as i8` produces `44`. When a conversion might fail, `try_into()` offers a different route; it returns a `Result` containing either a converted value or an error. The example brings `std::convert::TryInto` into scope before calling the method. section 2.3.3
Listing 2.5 The try_into() method converts between types
use std::convert::TryInto; #1
fn main() {
let a: i32 = 10;
let b: u16 = 100;
let b_ = b.try_into()
.unwrap(); #2
if a < b_ {
println!("Ten is less than one hundred.");
}
}
Compare the `try_into()` call with the direct `as` cast above; the listing shows the conversion before the comparison. section 2.3.3
Conversions also arise between representations, not just integer widths. Converting an NTP timestamp to a `chrono::DateTime` adjusts for different epochs and translates the fractional second. Because the representations have different precision, some accuracy may be lost. Implementing `From` defines such a conversion and normally makes the reciprocal `Into` implementation available automatically. section 9.9.3
Listing 9.14 Converting between chrono::DateTime and NTP timestamps
19 const NTP_TO_UNIX_SECONDS: i64 = 2_208_988_800; #1
22 #[derive(Default,Debug,Copy,Clone)]
23 struct NTPTimestamp { #2
24 seconds: u32, #2
25 fraction: u32, #2
26 }
#2
52 impl From<NTPTimestamp> for DateTime<Utc> {
53 fn from(ntp: NTPTimestamp) -> Self {
54 let secs = ntp.seconds as i64 - NTP_TO_UNIX_SECONDS;
55 let mut nanos = ntp.fraction as f64;
56 nanos *= 1e9; #3
57 nanos /= 2_f64.powi(32); #3
58
59 Utc.timestamp(secs, nanos as u32)
60 }
61 }
62
63 impl From<DateTime<Utc>> for NTPTimestamp {
64 fn from(utc: DateTime<Utc>) -> Self {
65 let secs = utc.timestamp() + NTP_TO_UNIX_SECONDS;
66 let mut fraction = utc.nanosecond() as f64;
67 fraction *= 2_f64.powi(32); #3
68 fraction /= 1e9; #3
69
70 NTPTimestamp {
71 seconds: secs as u32,
72 fraction: fraction as u32,
73 }
74 }
75 }
The timestamp implementation shows an epoch offset, numeric casts, and fractional-second arithmetic inside a `From` conversion. section 9.9.3




















