Skip to content

Commit 5320a9c

Browse files
committed
wip add try from methods
1 parent 2ad63fb commit 5320a9c

File tree

1 file changed

+108
-16
lines changed

1 file changed

+108
-16
lines changed

src/lib.rs

Lines changed: 108 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,104 @@ from_primitive_integer!(u64, approximate_float_unsigned);
12441244
from_primitive_integer!(u128, approximate_float_unsigned);
12451245
from_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+
12471345
impl<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

Comments
 (0)