You could require it implement the traits Add, AddAssign and Sub. If I remember right assign zero in a generic brings in some weird issues, but I can't remember what they are.
Okay, I looked up what the weird issue I was remembering with zero. The generic zero in std lib has been deprecated and the replacement I found was: http://rust-num.github.io/num/num/trait.Zero.html
Yeah, you can require generic ops, but you'll probably need num's Zero and One to complete this. There's a PrimInt trait which encapsulates a lot of the generic traits.
extern crate num_traits;
use num_traits::PrimInt;
trait LoopInt {
fn increment(&mut self, max: Self);
fn decrement(&mut self, max: Self);
}
impl<I> LoopInt for I
where I: PrimInt
{
fn increment(&mut self, max: Self) {
if *self == max - Self::one() {
*self = Self::zero()
} else {
*self = *self + Self::one()
}
}
fn decrement(&mut self, max: Self) {
if *self == Self::zero() {
*self = max - Self::one()
} else {
*self = *self - Self::one()
}
}
}