rsbag/src/reader/slice.rs

72 lines
1.7 KiB
Rust

use std::{io, ops::Deref};
use eyre::bail;
use super::{error::UnexpectedEof, BagReader};
use crate::{parse, Result};
#[derive(Clone)]
pub struct SliceReader<T> {
slice: T,
pos: usize,
}
impl<T> AsRef<T> for SliceReader<T> {
fn as_ref(&self) -> &T {
&self.slice
}
}
impl<T> SliceReader<T> {
pub fn into_inner(self) -> T {
self.slice
}
pub fn pos(&self) -> usize {
self.pos
}
}
impl<T> From<T> for SliceReader<T> {
fn from(slice: T) -> Self {
Self { slice, pos: 0 }
}
}
impl<T, U> BagReader for SliceReader<T>
where
T: Deref<Target = U>,
U: AsRef<[u8]> + ?Sized + 'static,
{
fn read_parser<'a, O: 'a, P>(&'a mut self, mut parser: P) -> Result<O>
where
P: nom::Parser<&'a [u8], O, parse::Error<&'a [u8]>>,
{
let slice = self.slice.deref().as_ref();
let input = slice.get(self.pos..).ok_or(UnexpectedEof)?;
match parser.parse(input) {
Ok((rest, output)) => {
self.pos += input.len() - rest.len();
Ok(output)
}
Err(nom::Err::Incomplete(_)) => bail!(UnexpectedEof),
Err(nom::Err::Error(e) | nom::Err::Failure(e)) => Err(e.into_owned().into()),
}
}
fn seek(&mut self, pos: io::SeekFrom) -> Result<()> {
match pos {
io::SeekFrom::Start(pos) => {
self.pos = pos as usize;
}
io::SeekFrom::End(pos) => {
self.pos = (self.slice.as_ref().len() as i64 + pos) as usize;
}
io::SeekFrom::Current(pos) => {
self.pos = ((self.pos as i64) + pos) as usize;
}
}
Ok(())
}
}