integer_or_float/str_conv/
mod.rs

1use core::fmt;
2use core::str::FromStr;
3
4use super::IntegerOrFloat::{self, *};
5use crate::ConversionError as IofConversionError;
6
7type ConversionError = IofConversionError<core::num::ParseFloatError>;
8
9use crate::{f_iof, i_iof};
10
11#[macro_use]
12mod ryu;
13use maybe as maybe_ryu;
14
15#[cfg(std)]
16impl From<IntegerOrFloat> for String {
17    fn from(iof: IntegerOrFloat) -> Self {
18        match iof {
19            IntegerOrFloat::Float(f) => { maybe_ryu!(f) },
20            IntegerOrFloat::Integer(i) => i.to_string(),
21        }
22    }
23}
24
25// this implements ToString iff feature(alloc), which has:
26// impl<T> ToString for T where T: std::fmt::Display, T: ?Sized { … };
27impl fmt::Display for IntegerOrFloat {
28    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
29        match self {
30            IntegerOrFloat::Float(f) => f.fmt(formatter),
31            IntegerOrFloat::Integer(i) => i.fmt(formatter),
32        }
33    }
34}
35
36impl fmt::Debug for IntegerOrFloat {
37    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
38        match self {
39            IntegerOrFloat::Float(f) => formatter.write_fmt(format_args!("Float({})", f)),
40            IntegerOrFloat::Integer(i) => formatter.write_fmt(format_args!("Integer({})", i)),
41        }
42    }
43}
44
45use core::convert::TryFrom;
46impl TryFrom<&str> for IntegerOrFloat {
47    type Error = ConversionError;
48    fn try_from(s: &str) -> Result<Self, Self::Error> {
49        match s.parse::<i_iof>() {
50            Ok(i) => Ok(Integer(i)),
51            Err(ice) => {
52                match s.parse::<f_iof>() {
53                    Ok(f) => Ok(Float(f)),
54                    Err(fce) => Err(ConversionError::kind_for_string(s, ice, fce))
55                }
56            }
57        }
58    }
59}
60
61#[cfg(feature = "num-traits")]
62impl num_traits::Num for IntegerOrFloat {
63    type FromStrRadixErr = ConversionError;
64    fn from_str_radix(s: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
65        if s.contains('.') {
66            Ok(Float(f_iof::from_str_radix(s, radix)?))
67        } else {
68            Ok(Integer(i_iof::from_str_radix(s, radix)?))
69        }
70    }
71}
72
73impl FromStr for IntegerOrFloat {
74    type Err = ConversionError;
75    fn from_str(s: &str) -> Result<Self, Self::Err> {
76        Self::try_from(s)
77    }
78}