Skip to content

Commit fc29969

Browse files
committed
add From and TryFrom methods
1 parent f61b878 commit fc29969

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

Diff for: Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ edition = "2018"
1616
[package.metadata.docs.rs]
1717
features = ["std", "num-bigint-std", "serde"]
1818

19-
[dependencies]
19+
[dependencies.paste]
20+
version = "1.0"
2021

2122
[dependencies.num-bigint]
2223
optional = true

Diff for: build.rs

+9
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,14 @@ fn main() {
44
println!("cargo:rustc-cfg=has_int_exp_fmt");
55
}
66

7+
let std = if ac.probe_sysroot_crate("std") {
8+
"std"
9+
} else {
10+
"core"
11+
};
12+
if ac.probe_path(&format!("{}::convert::TryFrom", std)) {
13+
autocfg::emit("has_try_from");
14+
}
15+
716
autocfg::rerun_path("build.rs");
817
}

Diff for: src/from.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use crate::{FromPrimitive, Ratio};
2+
3+
#[cfg(has_try_from)]
4+
use crate::{approximate_float, approximate_float_unsigned};
5+
#[cfg(has_try_from)]
6+
use core::convert::TryFrom;
7+
8+
macro_rules! impl_try_from {
9+
( $($name:ty),* => $into:ty ; $approx:ident) => {
10+
$(
11+
#[cfg(has_try_from)]
12+
impl TryFrom<$name> for Ratio<$into> {
13+
type Error = ();
14+
paste::paste! {
15+
fn try_from(n: $name) -> Result<Self, ()> {
16+
<$into as FromPrimitive>::[<from_ $name>](n)
17+
.map(Ratio::from_integer)
18+
.ok_or(())
19+
}
20+
}
21+
}
22+
)*
23+
24+
#[cfg(has_try_from)]
25+
impl TryFrom<f32> for Ratio<$into> {
26+
type Error = ();
27+
fn try_from(n: f32) -> Result<Self, ()> {
28+
$approx(n, 10e-20, 30).ok_or(())
29+
}
30+
}
31+
32+
#[cfg(has_try_from)]
33+
impl TryFrom<f64> for Ratio<$into> {
34+
type Error = ();
35+
fn try_from(n: f64) -> Result<Self, ()> {
36+
$approx(n, 10e-20, 30).ok_or(())
37+
}
38+
}
39+
40+
};
41+
}
42+
43+
impl_try_from!(i8, u16, i16, u32, i32, u64, i64, u128, i128 => u8 ; approximate_float_unsigned);
44+
impl_try_from!(u8, u16, i16, u32, i32, u64, i64, u128, i128 => i8 ; approximate_float);
45+
46+
impl_try_from!(i16, u32, i32, u64, i64, u128, i128 => u16 ; approximate_float_unsigned);
47+
impl_try_from!(u16, u32, i32, u64, i64, u128, i128 => i16 ; approximate_float);
48+
49+
impl_try_from!(i32, u64, i64, u128, i128 => u32 ; approximate_float_unsigned);
50+
impl_try_from!(u32, u64, i64, u128, i128 => i32 ; approximate_float);
51+
52+
impl_try_from!(i64, u128, i128 => u64 ; approximate_float_unsigned);
53+
impl_try_from!(u64, u128, i128 => i64 ; approximate_float);
54+
55+
impl_try_from!(i128 => u128 ; approximate_float_unsigned);
56+
impl_try_from!(u128 => i128 ; approximate_float);
57+
58+
macro_rules! impl_from {
59+
( $($name:ty),* => $into:ty) => {
60+
$(
61+
impl From<$name> for Ratio<$into> {
62+
paste::paste! {
63+
fn from(n: $name) -> Self {
64+
<$into as FromPrimitive>::[< from_ $name>](n)
65+
.map(Ratio::from_integer)
66+
.unwrap()
67+
}
68+
}
69+
}
70+
)*
71+
};
72+
}
73+
74+
impl_from!(u8, u16, u32, u64 => u128);
75+
impl_from!(u8, i8, u16, i16, u32, i32, u64, i64 => i128);
76+
77+
impl_from!(u8, u16, u32 => u64);
78+
impl_from!(u8, i8, u16, i16, u32, i32 => i64);
79+
80+
impl_from!(u8, u16 => u32);
81+
impl_from!(u8, i8, u16, i16 => i32);
82+
83+
impl_from!(u8 => u16);
84+
impl_from!(u8, i8 => i16);

Diff for: src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ use num_traits::{
4444
Pow, Signed, Zero,
4545
};
4646

47+
mod from;
4748
mod pow;
4849

4950
/// Represents the ratio between two numbers.

0 commit comments

Comments
 (0)