1 /// Find and parse sign and get remaining bytes.
3 fn parse_sign
<'a
>(bytes
: &'a
[u8]) -> (bool
, &'a
[u8]) {
5 Some(&b'
+'
) => (true, &bytes
[1..]),
6 Some(&b'
-'
) => (false, &bytes
[1..]),
11 // Convert u8 to digit.
13 fn to_digit(c
: u8) -> Option
<u32> {
14 (c
as char).to_digit(10)
17 // Add digit from exponent.
19 fn add_digit_i32(value
: i32, digit
: u32) -> Option
<i32> {
20 return value
.checked_mul(10)?
.checked_add(digit
as i32);
23 // Subtract digit from exponent.
25 fn sub_digit_i32(value
: i32, digit
: u32) -> Option
<i32> {
26 return value
.checked_mul(10)?
.checked_sub(digit
as i32);
29 // Convert character to digit.
31 fn is_digit(c
: u8) -> bool
{
35 // Split buffer at index.
37 fn split_at_index
<'a
>(digits
: &'a
[u8], index
: usize) -> (&'a
[u8], &'a
[u8]) {
38 (&digits
[..index
], &digits
[index
..])
41 /// Consume until a an invalid digit is found.
43 /// - `digits` - Slice containing 0 or more digits.
45 fn consume_digits
<'a
>(digits
: &'a
[u8]) -> (&'a
[u8], &'a
[u8]) {
46 // Consume all digits.
48 while index
< digits
.len() && is_digit(digits
[index
]) {
51 split_at_index(digits
, index
)
56 fn ltrim_zero
<'a
>(bytes
: &'a
[u8]) -> &'a
[u8] {
57 let count
= bytes
.iter().take_while(|&&si
| si
== b'
0'
).count();
63 fn rtrim_zero
<'a
>(bytes
: &'a
[u8]) -> &'a
[u8] {
64 let count
= bytes
.iter().rev().take_while(|&&si
| si
== b'
0'
).count();
65 let index
= bytes
.len() - count
;
72 /// Parse the exponent of the float.
74 /// * `exponent` - Slice containing the exponent digits.
75 /// * `is_positive` - If the exponent sign is positive.
76 fn parse_exponent(exponent
: &[u8], is_positive
: bool
) -> i32 {
77 // Parse the sign bit or current data.
78 let mut value
: i32 = 0;
82 value
= match add_digit_i32(value
, to_digit(*c
).unwrap()) {
84 None
=> return i32::max_value(),
90 value
= match sub_digit_i32(value
, to_digit(*c
).unwrap()) {
92 None
=> return i32::min_value(),
101 pub fn case_insensitive_starts_with
<'a
, 'b
, Iter1
, Iter2
>(mut x
: Iter1
, mut y
: Iter2
) -> bool
103 Iter1
: Iterator
<Item
= &'a
u8>,
104 Iter2
: Iterator
<Item
= &'b
u8>,
106 // We use a faster optimization here for ASCII letters, which NaN
107 // and infinite strings **must** be. [A-Z] is 0x41-0x5A, while
108 // [a-z] is 0x61-0x7A. Therefore, the xor must be 0 or 32 if they
109 // are case-insensitive equal, but only if at least 1 of the inputs
110 // is an ASCII letter.
116 let yi
= *yi
.unwrap();
117 let is_not_equal
= x
.next().map_or(true, |&xi
| {
119 xor
!= 0 && xor
!= 0x20
127 /// Parse float from input bytes, returning the float and the remaining bytes.
129 /// * `bytes` - Array of bytes leading with float-data.
130 pub fn parse_float
<'a
, F
>(bytes
: &'a
[u8]) -> (F
, &'a
[u8])
132 F
: minimal_lexical
::Float
,
137 let (is_positive
, bytes
) = parse_sign(bytes
);
139 // Check NaN, Inf, Infinity
140 if case_insensitive_starts_with(bytes
.iter(), b
"NaN".iter()) {
141 let mut float
= F
::from_bits(F
::EXPONENT_MASK
| (F
::HIDDEN_BIT_MASK
>> 1));
145 return (float
, &bytes
[3..]);
146 } else if case_insensitive_starts_with(bytes
.iter(), b
"Infinity".iter()) {
147 let mut float
= F
::from_bits(F
::EXPONENT_MASK
);
151 return (float
, &bytes
[8..]);
152 } else if case_insensitive_starts_with(bytes
.iter(), b
"inf".iter()) {
153 let mut float
= F
::from_bits(F
::EXPONENT_MASK
);
157 return (float
, &bytes
[3..]);
160 // Extract and parse the float components:
164 let (integer_slc
, bytes
) = consume_digits(bytes
);
165 let (fraction_slc
, bytes
) = match bytes
.first() {
166 Some(&b'
.'
) => consume_digits(&bytes
[1..]),
167 _
=> (&bytes
[..0], bytes
),
169 let (exponent
, bytes
) = match bytes
.first() {
170 Some(&b'e'
) | Some(&b'E'
) => {
171 // Extract and parse the exponent.
172 let (is_positive
, bytes
) = parse_sign(&bytes
[1..]);
173 let (exponent
, bytes
) = consume_digits(bytes
);
174 (parse_exponent(exponent
, is_positive
), bytes
)
179 if bytes
.len() == start
.len() {
180 return (F
::from_u64(0), bytes
);
183 // Note: You may want to check and validate the float data here:
184 // 1). Many floats require integer or fraction digits, if a fraction
186 // 2). All floats require either integer or fraction digits.
187 // 3). Some floats do not allow a '+' sign before the significant digits.
188 // 4). Many floats require exponent digits after the exponent symbol.
189 // 5). Some floats do not allow a '+' sign before the exponent.
191 // We now need to trim leading and trailing 0s from the integer
192 // and fraction, respectively. This is required to make the
193 // fast and moderate paths more efficient, and for the slow
195 let integer_slc
= ltrim_zero(integer_slc
);
196 let fraction_slc
= rtrim_zero(fraction_slc
);
198 // Create the float and return our data.
200 minimal_lexical
::parse_float(integer_slc
.iter(), fraction_slc
.iter(), exponent
);
217 (184467440000000000000.0, b
!("\x00\x00006")),
218 parse_float
::<f32>(b
"000184467440737095516150\x00\x00006")
225 (184467440737095500000.0, b
!("\x00\x00006")),
226 parse_float
::<f64>(b
"000184467440737095516150\x00\x00006")