I want to implement a new type wrapper around a usize to help define an API.
But internally I want to be able to coerce this type into a usize as easily as possible. For example I'm using it for lots of array work, slicing, incrementing, etc:
- Take slices from an
array[..newtype] - Increment
newtype += 1 - Compare to
newtype < array.len() - Etc
To this point I've been implementing each new trait as I need it Add, AddAssign, PartialEq, etc. And that started to get old... so I'm looking for an alternative.
I tried implementing AsRef<usize>, and that means I don't have to implement all the other traits, but then I have to sprinkle newtype.as_ref() all through my code.
Now I've just found Deref and that seems to do what I want and adds just * as extra syntax. But the trait documentation says it should only be used for smart pointers.
My questions... is it OK to use Deref for this case? Is there some better pattern that will also make this easy? Here's an example of the kind of code I want to write:
use std::ops::Deref;
pub struct Index(usize);
impl Deref for Index {
type Target = usize;
fn deref(&self) -> &usize {
&self.0
}
}
pub fn slice_array(items: &[u8], range: Range<Index>) -> &[u8] {
assert!(items.len() >= *range.end);
&items[*range.start..*range.end]
}