lexical_parse_float/
api.rs

1////! Implements the algorithm in terms of the lexical API.
2
3#![doc(hidden)]
4
5#[cfg(feature = "f16")]
6use lexical_util::bf16::bf16;
7use lexical_util::error::Error;
8#[cfg(feature = "f16")]
9use lexical_util::f16::f16;
10use lexical_util::format::{is_valid_options_punctuation, NumberFormat, STANDARD};
11use lexical_util::{from_lexical, from_lexical_with_options};
12
13use crate::options::Options;
14use crate::parse::ParseFloat;
15
16// API
17
18const DEFAULT_OPTIONS: Options = Options::new();
19
20/// Implement `FromLexical` for numeric type.
21///
22/// Need to inline these, otherwise code generation is sub-optimal.
23/// For some reason, it can't determine some of the const evaluations
24/// can actually be evaluated at compile-time, which causes major branching
25/// issues.
26macro_rules! float_from_lexical {
27    ($($t:ident)*) => ($(
28        impl FromLexical for $t {
29            #[cfg_attr(not(feature = "compact"), inline)]
30            fn from_lexical(bytes: &[u8]) -> lexical_util::result::Result<Self>
31            {
32                Self::parse_complete::<STANDARD>(bytes, &DEFAULT_OPTIONS)
33            }
34
35            #[cfg_attr(not(feature = "compact"), inline)]
36            fn from_lexical_partial(
37                bytes: &[u8],
38            ) -> lexical_util::result::Result<(Self, usize)>
39            {
40                Self::parse_partial::<STANDARD>(bytes, &DEFAULT_OPTIONS)
41            }
42        }
43
44        impl FromLexicalWithOptions for $t {
45            type Options = Options;
46
47            #[cfg_attr(not(feature = "compact"), inline)]
48            fn from_lexical_with_options<const FORMAT: u128>(
49                bytes: &[u8],
50                options: &Self::Options,
51            ) -> lexical_util::result::Result<Self>
52            {
53                let format = NumberFormat::<{ FORMAT }> {};
54                if !format.is_valid() {
55                    return Err(format.error());
56                } else if !is_valid_options_punctuation(FORMAT, options.exponent(), options.decimal_point()) {
57                    return Err(Error::InvalidPunctuation);
58                }
59                Self::parse_complete::<FORMAT>(bytes, options)
60            }
61
62            #[cfg_attr(not(feature = "compact"), inline)]
63            fn from_lexical_partial_with_options<const FORMAT: u128>(
64                bytes: &[u8],
65                options: &Self::Options,
66            ) -> lexical_util::result::Result<(Self, usize)>
67            {
68                Self::parse_partial::<FORMAT>(bytes, options)
69            }
70        }
71    )*)
72}
73
74from_lexical! {}
75from_lexical_with_options! {}
76float_from_lexical! { f32 f64 }
77
78#[cfg(feature = "f16")]
79float_from_lexical! { bf16 f16 }