use std::io::{ BufReader, SeekFrom };
use std::io::{ Read, Write, Seek };
use std;
use crate::stores::{ Queryable, StorageSet };
use crate::pack::read::packfile_read;
use crate::errors::Result;
use crate::pack::Packfile;
use crate::objects::Type;
use crate::id::Id;
pub type GetObject = Fn(&Id) -> Result<Option<(Type, Box<std::io::Read>)>>;
pub struct Reader<R> {
read: Box<Fn() -> Result<R>>,
}
impl<R: Read + Seek + 'static> Reader<R> {
pub fn new<C>(func: C) -> Self
where C: Fn() -> Result<R> + 'static {
Reader {
read: Box::new(func)
}
}
}
impl<R: Read + Seek + std::fmt::Debug> Packfile for Reader<R> {
fn read_bounds<W: Write, S: Queryable>(
&self,
start: u64,
end: u64,
output: &mut W,
backends: &StorageSet<S>
) -> Result<Type> {
let handle = (self.read)()?;
let mut buffered_file = BufReader::new(handle);
buffered_file.seek(SeekFrom::Start(start))?;
let packfile_type = packfile_read(&mut buffered_file, output, &mut 0)?;
let obj_type = packfile_type.decompress(
start,
&mut buffered_file,
output,
Some(backends)
)?;
Ok(obj_type)
}
}