scolapasta_int_parse/
parser.rsuse alloc::string::String;
use crate::error::ArgumentError;
use crate::subject::IntegerString;
#[must_use]
#[derive(Default, Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum Sign {
#[default]
Positive,
Negative,
}
#[must_use]
#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum State<'a> {
Initial(IntegerString<'a>),
Sign(IntegerString<'a>, Sign),
Accumulate(IntegerString<'a>, String),
}
impl<'a> State<'a> {
#[inline]
pub fn new(subject: IntegerString<'a>) -> Self {
Self::Initial(subject)
}
pub fn set_sign(self, sign: Sign) -> Result<Self, ArgumentError<'a>> {
match self {
Self::Sign(subject, _) | Self::Accumulate(subject, _) => Err(subject.into()),
Self::Initial(subject) => Ok(Self::Sign(subject, sign)),
}
}
pub fn collect_digit(self, digit: u8) -> Self {
const PRE_ALLOCATED_DIGIT_CAPACITY: usize = 21;
match self {
Self::Initial(arg) => {
let mut digits = String::with_capacity(PRE_ALLOCATED_DIGIT_CAPACITY);
digits.push(char::from(digit));
Self::Accumulate(arg, digits)
}
Self::Sign(arg, sign) => {
let mut digits = String::with_capacity(PRE_ALLOCATED_DIGIT_CAPACITY);
if let Sign::Negative = sign {
digits.push('-');
}
digits.push(char::from(digit));
Self::Accumulate(arg, digits)
}
Self::Accumulate(arg, mut digits) => {
digits.push(char::from(digit));
Self::Accumulate(arg, digits)
}
}
}
pub fn into_numeric_string(self) -> Result<String, ArgumentError<'a>> {
match self {
Self::Accumulate(_, digits) => Ok(digits),
Self::Initial(subject) | Self::Sign(subject, _) => Err(subject.into()),
}
}
}