use {
crate::{
de::Deserializer,
error::{ErrorCode::*, Result},
},
serde::de::Visitor,
};
pub(crate) struct Number<'de> {
negative: bool,
s: &'de str,
has_float_chars: bool,
}
impl<'de> Number<'de> {
pub fn read<'a>(
de: &'a mut Deserializer<'de>,
) -> Result<Self> {
de.eat_shit()?;
let mut negative = false;
let mut has_float_chars = false;
for (idx, ch) in de.input().char_indices() {
match ch {
'0'..='9' => { }
'-' if idx == 0 => {
negative = true;
}
'-' | '+' | '.' | 'e' | 'E' => {
has_float_chars = true;
}
_ => {
let s = de.start(idx);
de.advance(idx); return Ok(Self {
negative, s, has_float_chars
});
}
}
}
let s = de.take_all();
Ok(Self {
negative, s, has_float_chars
})
}
pub fn visit<'a, V>(
&self,
de: &'a mut Deserializer<'de>,
visitor: V,
) -> Result<V::Value>
where
V: Visitor<'de>,
{
if self.has_float_chars {
let v: f64 = self.s.parse()
.map_err(|_| de.err(ExpectedF64))?;
visitor.visit_f64(v)
} else if self.negative {
let v: i64 = self.s.parse()
.map_err(|_| de.err(ExpectedI64))?;
visitor.visit_i64(v)
} else {
let v: u64 = self.s.parse()
.map_err(|_| de.err(ExpectedU64))?;
visitor.visit_u64(v)
}
}
}