@@ -1244,6 +1244,104 @@ from_primitive_integer!(u64, approximate_float_unsigned);
12441244from_primitive_integer ! ( u128 , approximate_float_unsigned) ;
12451245from_primitive_integer ! ( usize , approximate_float_unsigned) ;
12461246
1247+ macro_rules! try_from_impl {
1248+ ( $typ: ty, $approx: ident) => {
1249+ // impl TryFrom<i32> for Ratio<$typ> {
1250+ // type Error = ();
1251+ // fn try_from(n: i32) -> Result<Self, ()> {
1252+ // <$typ as FromPrimitive>::from_i32(n)
1253+ // .map(Ratio::from_integer)
1254+ // .ok_or(())
1255+ // }
1256+ // }
1257+
1258+ impl TryFrom <i64 > for Ratio <$typ> {
1259+ type Error = ( ) ;
1260+ fn try_from( n: i64 ) -> Result <Self , ( ) > {
1261+ <$typ as FromPrimitive >:: from_i64( n)
1262+ . map( Ratio :: from_integer)
1263+ . ok_or( ( ) )
1264+ }
1265+ }
1266+
1267+ impl TryFrom <i128 > for Ratio <$typ> {
1268+ type Error = ( ) ;
1269+ fn try_from( n: i128 ) -> Result <Self , ( ) > {
1270+ <$typ as FromPrimitive >:: from_i128( n)
1271+ . map( Ratio :: from_integer)
1272+ . ok_or( ( ) )
1273+ }
1274+ }
1275+
1276+ // impl TryFrom<u32> for Ratio<$typ> {
1277+ // type Error = ();
1278+ // fn try_from(n: u32) -> Result<Self, ()> {
1279+ // <$typ as FromPrimitive>::from_u32(n)
1280+ // .map(Ratio::from_integer)
1281+ // .ok_or(())
1282+ // }
1283+ // }
1284+
1285+ impl TryFrom <u64 > for Ratio <$typ> {
1286+ type Error = ( ) ;
1287+ fn try_from( n: u64 ) -> Result <Self , ( ) > {
1288+ <$typ as FromPrimitive >:: from_u64( n)
1289+ . map( Ratio :: from_integer)
1290+ . ok_or( ( ) )
1291+ }
1292+ }
1293+
1294+ impl TryFrom <u128 > for Ratio <$typ> {
1295+ type Error = ( ) ;
1296+ fn try_from( n: u128 ) -> Result <Self , ( ) > {
1297+ <$typ as FromPrimitive >:: from_u128( n)
1298+ . map( Ratio :: from_integer)
1299+ . ok_or( ( ) )
1300+ }
1301+ }
1302+
1303+ impl TryFrom <f32 > for Ratio <$typ> {
1304+ type Error = ( ) ;
1305+ fn try_from( n: f32 ) -> Result <Self , ( ) > {
1306+ $approx( n, 10e-20 , 30 ) . ok_or( ( ) )
1307+ }
1308+ }
1309+
1310+ impl TryFrom <f64 > for Ratio <$typ> {
1311+ type Error = ( ) ;
1312+ fn try_from( n: f64 ) -> Result <Self , ( ) > {
1313+ $approx( n, 10e-20 , 30 ) . ok_or( ( ) )
1314+ }
1315+ }
1316+ } ;
1317+ }
1318+ use std:: convert:: TryFrom ;
1319+
1320+ // TODO
1321+ // need to exclude generation of the version for the same value
1322+ try_from_impl ! ( i8 , approximate_float) ;
1323+ try_from_impl ! ( i16 , approximate_float) ;
1324+ try_from_impl ! ( i32 , approximate_float) ;
1325+ // try_from_impl!(i64, approximate_float);
1326+ // try_from_impl!(i128, approximate_float);
1327+ try_from_impl ! ( isize , approximate_float) ;
1328+
1329+ try_from_impl ! ( u8 , approximate_float_unsigned) ;
1330+ try_from_impl ! ( u16 , approximate_float_unsigned) ;
1331+ try_from_impl ! ( u32 , approximate_float_unsigned) ;
1332+ // try_from_impl!(u64, approximate_float_unsigned);
1333+ // try_from_impl!(u128, approximate_float_unsigned);
1334+ try_from_impl ! ( usize , approximate_float_unsigned) ;
1335+
1336+ #[ test]
1337+ fn try_from_impl ( ) {
1338+ debug_assert_eq ! ( Err ( ( ) ) , Ratio :: <i8 >:: try_from( 1000000i64 ) ) ;
1339+ debug_assert_eq ! (
1340+ Ok ( Ratio :: <i8 >:: from_integer( 11 ) ) ,
1341+ Ratio :: <i8 >:: try_from( 11i64 )
1342+ ) ;
1343+ }
1344+
12471345impl < T : Integer + Signed + Bounded + NumCast + Clone > Ratio < T > {
12481346 pub fn approximate_float < F : FloatCore + NumCast > ( f : F ) -> Option < Ratio < T > > {
12491347 // 1/10e-20 < 1/2**32 which seems like a good default, and 30 seems
@@ -2205,13 +2303,10 @@ mod test {
22052303 let big = T :: max_value ( ) / two. clone ( ) / two. clone ( ) * two. clone ( ) ;
22062304 let _1_big: Ratio < T > = Ratio :: new ( T :: one ( ) , big. clone ( ) ) ;
22072305 let _2_3: Ratio < T > = Ratio :: new ( two. clone ( ) , _3. clone ( ) ) ;
2208- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2306+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
22092307 let expected = Ratio :: new ( T :: one ( ) , big / two. clone ( ) * _3. clone ( ) ) ;
2210- assert_eq ! ( expected. clone( ) , _1_big. clone( ) * _2_3. clone( ) ) ;
2211- assert_eq ! (
2212- Some ( expected. clone( ) ) ,
2213- _1_big. clone( ) . checked_mul( & _2_3. clone( ) )
2214- ) ;
2308+ assert_eq ! ( expected, _1_big. clone( ) * _2_3. clone( ) ) ;
2309+ assert_eq ! ( Some ( expected. clone( ) ) , _1_big. checked_mul( & _2_3) ) ;
22152310 assert_eq ! ( expected, {
22162311 let mut tmp = _1_big;
22172312 tmp *= _2_3;
@@ -2221,7 +2316,7 @@ mod test {
22212316 // big/3 * 3 = big/1
22222317 // make big = max/2, but make it indivisible by 3
22232318 let big = T :: max_value ( ) / two / _3. clone ( ) * _3. clone ( ) + T :: one ( ) ;
2224- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2319+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
22252320 let big_3 = Ratio :: new ( big. clone ( ) , _3. clone ( ) ) ;
22262321 let expected = Ratio :: new ( big, T :: one ( ) ) ;
22272322 assert_eq ! ( expected, big_3. clone( ) * _3. clone( ) ) ;
@@ -2292,15 +2387,12 @@ mod test {
22922387 // 1/big / 3/2 = 1/(max/4*3), where big is max/2
22932388 // big ~ max/2, and big is divisible by 2
22942389 let big = T :: max_value ( ) / two. clone ( ) / two. clone ( ) * two. clone ( ) ;
2295- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2390+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
22962391 let _1_big: Ratio < T > = Ratio :: new ( T :: one ( ) , big. clone ( ) ) ;
22972392 let _3_two: Ratio < T > = Ratio :: new ( _3. clone ( ) , two. clone ( ) ) ;
22982393 let expected = Ratio :: new ( T :: one ( ) , big / two. clone ( ) * _3. clone ( ) ) ;
2299- assert_eq ! ( expected. clone( ) , _1_big. clone( ) / _3_two. clone( ) ) ;
2300- assert_eq ! (
2301- Some ( expected. clone( ) ) ,
2302- _1_big. clone( ) . checked_div( & _3_two. clone( ) )
2303- ) ;
2394+ assert_eq ! ( expected, _1_big. clone( ) / _3_two. clone( ) ) ;
2395+ assert_eq ! ( Some ( expected. clone( ) ) , _1_big. checked_div( & _3_two) ) ;
23042396 assert_eq ! ( expected, {
23052397 let mut tmp = _1_big;
23062398 tmp /= _3_two;
@@ -2310,7 +2402,7 @@ mod test {
23102402 // 3/big / 3 = 1/big where big is max/2
23112403 // big ~ max/2, and big is not divisible by 3
23122404 let big = T :: max_value ( ) / two / _3. clone ( ) * _3. clone ( ) + T :: one ( ) ;
2313- assert_eq ! ( None , big. clone ( ) . checked_mul( & _3. clone ( ) ) ) ;
2405+ assert_eq ! ( None , big. checked_mul( & _3) ) ;
23142406 let _3_big = Ratio :: new ( _3. clone ( ) , big. clone ( ) ) ;
23152407 let expected = Ratio :: new ( T :: one ( ) , big) ;
23162408 assert_eq ! ( expected, _3_big. clone( ) / _3. clone( ) ) ;
@@ -2688,8 +2780,8 @@ mod test {
26882780 1.0 / 2f32 . powf ( 100. ) ,
26892781 ( "1" , "1267650600228229401496703205376" ) ,
26902782 ) ;
2691- test ( 684729.48391f32 , ( "1369459" , "2" ) ) ;
2692- test ( -8573.5918555f32 , ( "-4389679" , "512" ) ) ;
2783+ test ( 684_729.5_f32 , ( "1369459" , "2" ) ) ;
2784+ test ( -8_573.592_f32 , ( "-4389679" , "512" ) ) ;
26932785
26942786 // f64
26952787 test (
0 commit comments