use core::fmt;
#[derive(Debug, Copy, Clone)]
pub struct SciNumber979b {
integer: u8,
decimal: u8,
epositive: bool,
exponent: u8,
}
#[derive(Debug)]
pub struct SciNumberError;
impl SciNumber979b {
pub fn try_new(
integer: u8,
decimal: u8,
epositive: bool,
exponent: u8,
) -> Result<Self, SciNumberError> {
if integer < 10 && decimal < 100 && exponent < 11 {
Ok(SciNumber979b {
integer,
decimal,
epositive,
exponent,
})
} else {
Err(SciNumberError)
}
}
pub fn into_u32(x: SciNumber979b) -> u32 {
(x.integer as u32) << 24
| (x.decimal as u32) << 16
| (x.epositive as u32) << 8
| (x.exponent as u32)
}
pub fn from_ascii(s: &[u8]) -> Result<Self, SciNumberError> {
let len = s.len();
if len < 7 {
Err(SciNumberError)
} else {
for (i, ch) in s.iter().enumerate().take(len) {
if i == 1 || i == 4 || i == 5 {
continue;
}
if *ch < b'0' || *ch > b'9' {
return Err(SciNumberError);
}
}
let epositive = s[5] == b'+';
Ok(if s.len() < 8 {
Self {
integer: s[0] - b'0',
decimal: (s[2] - b'0') * 10 + s[3] - b'0',
epositive,
exponent: s[6] - b'0',
}
} else {
Self {
integer: s[0] - b'0',
decimal: (s[2] - b'0') * 10 + s[3] - b'0',
epositive,
exponent: (s[6] - b'0') * 10 + s[7] - b'0',
}
})
}
}
}
impl fmt::Display for SciNumber979b {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let exponent_sign = if self.epositive { '+' } else { '-' };
write!(
f,
"{:01}.{:02}E{}{:01}",
self.integer, self.decimal, exponent_sign, self.exponent,
)
}
}