use crate::{Error, FixedField};
pub const RECORD_LENGTH: usize = 132;
pub trait Record<'a>: Sized {
fn parse(fields: Fields<'a>) -> Result<Self, Error>;
fn from_bytes(bytes: &'a [u8]) -> Result<Self, Error> {
if bytes.len() == RECORD_LENGTH {
Self::parse(Fields::new(bytes))
} else {
Err(Error::InvalidRecordLength {
actual: bytes.len(),
})
}
}
}
pub struct Fields<'a> {
bytes: &'a [u8],
index: usize,
}
impl<'a> Fields<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
Self { bytes, index: 0 }
}
#[inline]
pub fn next<F>(&mut self) -> Result<F, Error>
where
F: FixedField<'a>,
{
let field = F::from_bytes(&self.bytes[self.index..])?;
self.index += F::LENGTH;
Ok(field)
}
#[inline]
pub fn skip(&mut self, n: usize) -> &mut Self {
self.index += n;
self
}
#[inline]
pub fn get<F>(&mut self, position: usize) -> Result<F, Error>
where
F: FixedField<'a>,
{
self.index = position - 1;
self.next()
}
}