use std::ops::Mul; #[derive(Clone,Copy,Debug,Hash)] pub struct Ratio{ pub(crate)num:Num, pub(crate)den:Den, } impl Ratio{ pub const fn new(num:Num,den:Den)->Self{ Self{num,den} } } impl PartialEq for Ratio where Den:Copy, Rhs:Mul+Copy, Num:PartialEq<>::Output> { fn eq(&self,rhs:&Rhs)->bool{ self.num.eq(&rhs.mul(self.den)) } } /* //You can't do Ratio==Ratio I guess impl Eq for Ratio where Num:Mul, >::Output:PartialEq {} */ // num/den == rhs // num == rhs * den impl PartialOrd for Ratio where Den:Copy, Rhs:Mul+Copy, Num:PartialOrd<>::Output> { fn partial_cmp(&self,rhs:&Rhs)->Option{ self.num.partial_cmp(&rhs.mul(self.den)) } } /* impl Ord for Ratio<>::Output,Den> where Rhs:Mul, Rhs:Ord, >::Output:Ord, { fn cmp(&self,other:&Rhs)->std::cmp::Ordering{ self.num.cmp(&other.mul(self.den)) } } */ impl,Den> std::ops::Neg for Ratio{ type Output=Ratio; fn neg(self)->Self::Output{ Ratio{ num:self.num.neg(), den:self.den, } } } // num/den + rhs == new_num/den // new_num = num + rhs * den macro_rules! impl_operator { ($struct:ident,$trait:ident,$method:ident)=>{ impl core::ops::$trait for $struct where Den:Copy, Rhs:Mul, Num:core::ops::$trait<>::Output>, { type Output=$struct<>::Output>>::Output,Den>; fn $method(self,rhs:Rhs)->Self::Output{ $struct{ num:self.num.$method(rhs.mul(self.den)), den:self.den, } } } }; } macro_rules! impl_assign_operator{ ($struct:ident,$trait:ident,$method:ident)=>{ impl core::ops::$trait for $struct where Den:Copy, Rhs:Mul, Num:core::ops::$trait<>::Output>, { fn $method(&mut self,rhs:Rhs){ self.num.$method(rhs.mul(self.den)); } } }; } // Impl arithmetic operators impl_assign_operator!(Ratio,AddAssign,add_assign); impl_operator!(Ratio,Add,add); impl_assign_operator!(Ratio,SubAssign,sub_assign); impl_operator!(Ratio,Sub,sub); // num/den % rhs == new_num/den // new_num = num % (rhs * den) impl_assign_operator!(Ratio,RemAssign,rem_assign); impl_operator!(Ratio,Rem,rem); //mul and div is special impl Mul for Ratio where Num:Mul, { type Output=Ratio<>::Output,Den>; fn mul(self,rhs:Rhs)->Self::Output{ Ratio{ num:self.num.mul(rhs), den:self.den, } } } impl core::ops::MulAssign for Ratio where Num:core::ops::MulAssign, { fn mul_assign(&mut self,rhs:Rhs){ self.num.mul_assign(rhs); } } impl core::ops::Div for Ratio where Den:Mul, { type Output=Ratio>::Output>; fn div(self,rhs:Rhs)->Self::Output{ Ratio{ num:self.num, den:self.den.mul(rhs), } } } impl core::ops::DivAssign for Ratio where Den:core::ops::MulAssign, { fn div_assign(&mut self,rhs:Rhs){ self.den.mul_assign(rhs); } }