use crate::parsers::modular::error::{ModularParserError, NumberError};
use crate::parsers::modular::take_while_peekable::TakeWhilePeekable;
use std::iter::Peekable;
#[allow(clippy::manual_try_fold)]
pub fn parse_component<'b>(
input: &mut Peekable<impl Iterator<Item = &'b u8>>,
) -> Result<u64, ModularParserError> {
input.take_while_peekable(|&tok| tok.is_ascii_digit()).fold(
Err(ModularParserError::ExpectedNumericToken { got: None }),
|state: Result<u64, ModularParserError>, next| {
let next = u64::from(next - b'0');
match state {
Ok(0) => Err(ModularParserError::NumberError(NumberError::LeadingZero)),
Ok(value) => value
.checked_mul(10)
.and_then(|lhs| lhs.checked_add(next))
.ok_or(ModularParserError::NumberError(NumberError::Overflow)),
Err(ModularParserError::ExpectedNumericToken { got: None }) => Ok(next),
Err(err) => Err(err),
}
},
)
}
pub fn peek_is_dot<'b>(input: &mut Peekable<impl Iterator<Item = &'b u8>>) -> bool {
input.peek().map(|&&token| token == b'.').unwrap_or(false)
}
pub fn parse_dot<'b>(input: &mut impl Iterator<Item = &'b u8>) -> Result<(), ModularParserError> {
input
.next()
.filter(|&&token| token == b'.')
.map(|_| ())
.ok_or(ModularParserError::ExpectedSeparator { got: None })
}
pub fn is_done<'b>(input: &mut impl Iterator<Item = &'b u8>) -> Result<(), ModularParserError> {
match input.next() {
Some(&token) => Err(ModularParserError::ExpectedEndOfInput { got: token }),
None => Ok(()),
}
}