New Type Idiom

Source: https://doc.rust-lang.org/rust-by-example/generics/new_types.html

If you use the same type for different purposes, often it is better to create a new type for each purpose. The above source shows an example where i64 is used for both years and days to count an age. Since the same type i64 is used for two different purposes, you can create one new type for years and another new type for days as follows.

#![allow(unused)]
fn main() {
struct Years(i64);
struct Days(i64);
}

The benefit of doing this is that you can use the compiler's type checker to ensure that you are using i64 for the right purpose. If you make a call to a function that needs to use years instead of days, then you can use Years as the type instead of i64. This will make sure that you are passing the right value with the right type to the function that expects to use years, not days.

#![allow(unused)]
fn main() {
fn old_enough(age: &Years) -> bool {
    age.0 >= 18
}
}

The above function expects to use years, not days and now the compiler will make sure that you pass years, not days.

struct Years(i64);
struct Days(i64);

fn old_enough(age: &Years) -> bool {
    age.0 >= 18
}

fn main() {
    let years = Years(32);
    let days = Days(years.0 * 365);

    println!("{}", old_enough(&years));

    // Uncomment the following line and run it to see an error.
    // println!("{}", old_enough(&days));
}