I need a representation for 2D coordinates on a grid. I'm aware of the «newtype» pattern that helps avoid mistakes between width and height.
#[derive(Copy, Clone, Debug)]
pub struct Width(u8);
#[derive(Copy, Clone, Debug)]
pub struct Height(u8);
#[derive(Copy, Clone, Debug)]
pub struct Location {
pub x: Width,
pub y: Height,
}
I really like this pattern that usesthe type system to avoid mistakes such as inadvertently swapping width and height in function parameters.
However, this approach adds verbosity to my code; I end up destructuring a lot to access the inner data since I can't really work with my newtype value:
let Width(w) = width;
let Height(h) = height;
for a in 0..h {
for b in 0..w {
//DO SOMETHING HERE
}
}
Or
let Width(w) = width;
let Height(h) = height;
let mut map = vec![vec![0; w as usize]; h as usize];
I found how I could easily use arithmetic operators with my newtypes using the Add
and Sub
traits (even though it also has a verbosity burden) and I would like to know if there is a trait I can implement on my newtype to be able to use it in a range or to be casted as usize
.
Even better, is there a way to tell the compiler that I want my newtype to behave exactly as its content, without needing to manually implement every trait by myself? Something like this maybe:
#[derive(everything_from_inner)]
struct Height(u8)