1pub trait ParseNum {
2 fn parse_num<T: num::Num>(&self) -> Result<T, T::FromStrRadixErr>;
28}
29
30impl ParseNum for str {
32 fn parse_num<T: num::Num>(&self) -> Result<T, T::FromStrRadixErr> {
33 let (radix, trimmed_str) =
35 if self.starts_with("0x") || self.starts_with("0X") {
36 (16, &self[2..])
37 } else if self.starts_with("0b") || self.starts_with("0B") {
38 (2, &self[2..])
39 } else if self.starts_with("0o") || self.starts_with("0O") {
40 (8, &self[2..])
41 } else {
42 (10, self)
43 };
44
45 T::from_str_radix(trimmed_str, radix)
46 }
47}
48
49#[cfg(test)]
50mod test {
51 use super::ParseNum;
52
53 #[test]
54 fn conversion() {
55 assert_eq!("0".parse_num::<i32>().unwrap(), 0i32);
56 assert_eq!("10".parse_num::<f32>().unwrap(), 10f32);
57
58 assert_eq!("0x01".parse_num::<u16>().unwrap(), 1u16);
59 assert_eq!("0xFF".parse_num::<f64>().unwrap(), 255f64);
60 assert_eq!("0b1111".parse_num::<u8>().unwrap(), 0b1111u8);
61 assert_eq!("0o1463".parse_num::<u16>().unwrap(), 0o1463u16);
62
63 assert_eq!("0XfF".parse_num::<f64>().unwrap(), 255f64);
64 assert_eq!("0B1111".parse_num::<u8>().unwrap(), 0b1111u8);
65 assert_eq!("0O1463".parse_num::<u16>().unwrap(), 0o1463u16);
66 }
67
68 #[test]
69 fn fails() {
70 assert!("".parse_num::<i8>().is_err());
71 assert!("0b".parse_num::<u8>().is_err());
72 assert!("0o".parse_num::<i16>().is_err());
73 assert!("0x".parse_num::<u16>().is_err());
74
75 assert!("a".parse_num::<i8>().is_err());
76 assert!("0b2".parse_num::<u8>().is_err());
77 assert!("0o8".parse_num::<i16>().is_err());
78 assert!("0xg".parse_num::<u16>().is_err());
79 }
80}