use crate::impl_read_one_from_for_from_str;
#[cfg(feature = "c-compatible")]
mod inner {
use crate::ext::{Pattern, State};
#[derive(Debug, Clone, Copy, Default)]
pub(super) enum Float {
#[default]
Initial,
Sign,
I,
In,
Inf,
Infi,
Infin,
Infini,
Infinit,
Infinity,
N,
Na,
Nan,
Digits,
Dot,
DotAfterDigits,
DigitsAfterDot,
Exponent,
SignAfterExponent,
DigitAfterExponent,
}
impl Pattern for Float {
type Item = char;
#[inline]
fn step(&mut self, c: <Self as Pattern>::Item) -> bool {
match self {
Self::Initial => match c {
'+' | '-' => *self = Self::Sign,
'.' => *self = Self::Dot,
_ if c.is_ascii_digit() => *self = Self::Digits,
'I' | 'i' => *self = Self::I,
'N' | 'n' => *self = Self::N,
_ => return false,
},
Self::Sign => match c {
'.' => *self = Self::Dot,
_ if c.is_ascii_digit() => *self = Self::Digits,
'I' | 'i' => *self = Self::I,
'N' | 'n' => *self = Self::N,
_ => return false,
},
Self::I => {
match c {
'N' | 'n' => *self = Self::In,
_ => return false,
}
}
Self::In => match c {
'F' | 'f' => *self = Self::Inf,
_ => return false,
},
Self::Inf => match c {
'I' | 'i' => *self = Self::Infi,
_ => return false,
},
Self::Infi => match c {
'N' | 'n' => *self = Self::Infin,
_ => return false,
},
Self::Infin => match c {
'I' | 'i' => *self = Self::Infini,
_ => return false,
},
Self::Infini => match c {
'T' | 't' => *self = Self::Infinit,
_ => return false,
},
Self::Infinit => match c {
'Y' | 'y' => *self = Self::Infinity,
_ => return false,
},
Self::Infinity => return false,
Self::N => match c {
'A' | 'a' => *self = Self::Na,
_ => return false,
},
Self::Na => match c {
'N' | 'n' => *self = Self::Nan,
_ => return false,
},
Self::Nan => return false,
Self::Digits => match c {
'.' => *self = Self::DotAfterDigits,
'e' | 'E' => *self = Self::Exponent,
_ if c.is_ascii_digit() => {}
_ => return false,
},
Self::Dot | Self::DotAfterDigits => match c {
'e' | 'E' => *self = Self::Exponent,
_ if c.is_ascii_digit() => *self = Self::DigitsAfterDot,
_ => return false,
},
Self::DigitsAfterDot => match c {
'e' | 'E' => *self = Self::Exponent,
_ if c.is_ascii_digit() => {}
_ => return false,
},
Self::Exponent => {
match c {
'+' | '-' => *self = Self::SignAfterExponent,
_ if c.is_ascii_digit() => *self = Self::DigitAfterExponent,
_ => return false,
}
}
Self::SignAfterExponent => match c {
_ if c.is_ascii_digit() => *self = Self::DigitAfterExponent,
_ => return false,
},
Self::DigitAfterExponent => match c {
_ if c.is_ascii_digit() => {}
_ => return false,
},
}
true
}
#[inline]
fn state(&self) -> State {
match self {
Self::Inf
| Self::Infinity
| Self::Nan
| Self::Digits
| Self::DotAfterDigits
| Self::DigitsAfterDot
| Self::DigitAfterExponent => State::Stoppable,
_ => State::Unfulfilled,
}
}
}
}
#[cfg(feature = "c-compatible")]
impl_read_one_from_for_from_str!(
f32 f64 => inner::Float::Initial
);
#[cfg(not(feature = "c-compatible"))]
impl_read_one_from_for_from_str!(f32 f64);