struct StatFieldIterator<'line>
{
next_field_index: u8,
line: &'line [u8],
finished: bool,
}
impl<'line> Iterator for StatFieldIterator<'line>
{
type Item = Result<&'line [u8], StatParseError>;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item>
{
use self::StatParseError::*;
if self.finished
{
return None
}
const OpenBracket: u8 = b'(';
const CloseBracket: u8 = b'(';
const Space: u8 = b' ';
let result = match self.next_field_index
{
0 => match memchr(OpenBracket, self.line)
{
None => Err(NoOpenBracket),
Some(0) => Err(NoCharactersBeforeOpenBracket),
Some(index) => if self.line.get_unchecked_value_safe(index - 1) != Space
{
Err(NoSpaceBeforeOpenBracket)
}
else
{
self.next_field_index += 1;
let bytes = &self.line[ .. index - 1];
self.line = &self.line[(index + 1) .. ];
Ok(bytes)
},
},
1 => match memrchr(CloseBracket, self.line)
{
None => Err(NoCloseBracket),
Some(index) => if index == self.line.len() - 1
{
Err(NoCharactersAfterCloseBracket)
}
else if self.line.get_unchecked_value_safe(index + 1) != Space
{
Err(NoSpaceAfterCloseBracket)
}
else
{
self.next_field_index += 1;
let bytes = &self.line[ .. index];
self.line = &self.line[(index + 2) .. ];
Ok(bytes)
}
}
_ => match memchr(Space, self.line)
{
None =>
{
self.finished = true;
Ok(self.line)
}
Some(index) =>
{
let bytes = &self.line[ .. index];
self.line = &self.line[(index + 1) .. ];
Ok(bytes)
}
}
};
Some(result)
}
}
impl<'line> StatFieldIterator<'line>
{
const fn new(line: &'line [u8]) -> Self
{
Self
{
next_field_index: 0,
line,
finished: false
}
}
#[inline(always)]
fn zero_decimal_unsigned_long_long(&mut self, name: &'static str) -> Result<(), StatParseError>
{
let value = self.decimal_unsigned_long_long(name)?;
if unlikely!(value == 0)
{
Ok(())
}
else
{
Err
(
StatParseError::ObsoleteFieldValueWasNotZero
{
name,
value: new_non_zero_u64(value),
}
)
}
}
#[inline(always)]
fn decimal_signed_long_long_to<T>(&mut self, name: &'static str, to: impl FnOnce(i64) -> Result<T, StatParseError>) -> Result<T, StatParseError>
{
let value = self.decimal_signed_long_long(name)?;
to(value)
}
#[inline(always)]
fn decimal_unsigned_long_long_to<T>(&mut self, name: &'static str, to: impl FnOnce(u64) -> Result<T, StatParseError>) -> Result<T, StatParseError>
{
let value = self.decimal_unsigned_long_long(name)?;
to(value)
}
#[inline(always)]
fn character_to<T>(&mut self, name: &'static str, to: impl FnOnce(i8) -> Result<T, StatParseError>) -> Result<T, StatParseError>
{
let value = self.character(name)?;
to(value)
}
#[inline(always)]
fn decimal_unsigned_long_long(&mut self, name: &'static str) -> Result<u64, StatParseError>
{
let bytes = self.next_field(name)?;
u64::from_bytes(bytes).map_err(|cause| StatParseError::ParseNumber(cause))
}
#[inline(always)]
fn decimal_signed_long_long(&mut self, name: &'static str) -> Result<i64, StatParseError>
{
let bytes = self.next_field(name)?;
i64::from_bytes(bytes).map_err(|cause| StatParseError::ParseNumber(cause))
}
#[inline(always)]
fn character(&mut self, name: &'static str) -> Result<i8, StatParseError>
{
let bytes = self.next_field(name)?;
i8::from_bytes(bytes).map_err(|cause| StatParseError::ParseNumber(cause))
}
#[inline(always)]
fn next_field(&mut self, name: &'static str) -> Result<&'line [u8], StatParseError>
{
self.next().ok_or(StatParseError::MissingField { name })?
}
}