use crate::ser;
use num_traits::float::FloatCore;
use std::fmt::Write;
use zmij::Float;
pub(crate) fn push_float_string<F: Float + FloatCore>(
target: &mut String,
f: F,
) -> ser::Result<()> {
if f.is_nan() {
target.push_str(".nan");
} else if f.is_infinite() {
if f.is_sign_positive() {
target.push_str(".inf");
} else {
target.push_str("-.inf");
}
} else {
let mut buf = zmij::Buffer::new();
let s = buf.format_finite(f);
target.reserve(s.len() + 3);
if let Some(exp_pos) = s.find('e').or_else(|| s.find('E')) {
if !s[..exp_pos].contains('.') {
target.push_str(&s[..exp_pos]);
target.push_str(".0");
} else {
target.push_str(&s[..exp_pos]);
}
target.push_str(&s[exp_pos..=exp_pos]);
if !matches!(s.as_bytes().get(exp_pos + 1), Some(b'+' | b'-')) {
target.push('+');
}
target.push_str(&s[exp_pos + 1..]);
} else if !s.contains('.') {
target.push_str(s);
target.push_str(".0");
} else {
target.push_str(s);
}
}
Ok(())
}
pub(crate) fn write_float_string<F: Float + FloatCore, W: Write>(
target: &mut W,
f: F,
) -> ser::Result<()> {
if f.is_nan() {
target.write_str(".nan")?;
} else if f.is_infinite() {
if f.is_sign_positive() {
target.write_str(".inf")?;
} else {
target.write_str("-.inf")?;
}
} else {
let mut buf = zmij::Buffer::new();
let s = buf.format_finite(f);
if let Some(exp_pos) = s.find('e').or_else(|| s.find('E')) {
if !s[..exp_pos].contains('.') {
target.write_str(&s[..exp_pos])?;
target.write_str(".0")?;
} else {
target.write_str(&s[..exp_pos])?;
}
target.write_str(&s[exp_pos..=exp_pos])?;
if !matches!(s.as_bytes().get(exp_pos + 1), Some(b'+' | b'-')) {
target.write_char('+')?;
}
target.write_str(&s[exp_pos + 1..])?;
} else if !s.contains('.') {
target.write_str(s)?;
target.write_str(".0")?;
} else {
target.write_str(s)?;
}
}
Ok(())
}