72 lines
1.7 KiB
Rust
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(())
|
|
}
|
|
}
|