Search code examples
rustderivingnewtype

Automatically derive Add, Mul, Ord, etc. for a numeric type


What's the simplest way to create a custom type that behaves like a number?

I want type-checking that prevents mixing different units in my program, but I still want to be able to easily perform calculations on the type without casting back and forth (similar case to custom Centimeters and Inches types).

If I create:

struct Centimeters(f64);

then I have to implement Add, Mul, Ord and lots of other traits manually. That's a lot of boilerplate, and copy&pasting of this code creates a risk of breaking basic arithmetic in the program :)

Unfortunately #[derive(Add, Sub, …)] doesn't seem to be supported. Is there another standard trait/type/crate that could achieve similar effect?


Solution

  • Units of Measurement

    You should have a look at https://crates.io/crates/measurements. That crate contains definitions for many units of measurement like centimeters, feet, etc.

    Implementing traits for your newtypes

    There are now some crates that make it really easy to implement Add, Mul, etc. for your newtypes.

    derive_more

    // This needs rust in the 2018 edition
    extern crate derive_more;
    use derive_more::{Add, Mul};
    
    #[derive(Add, Mul)]
    struct Centimeters(i32);
    

    newtype_derive

    custom_derive! {
      #[derive(NewtypeAdd, NewtypeMul)]
      pub struct Centimeters(i32);
    }
    

    Traits with your own macro

    This answer has a nice macro to help you implement traits for your newtypes.