use std::fs::File;
use std::io::Error as IoError;
use std::io::Seek;
use std::io::SeekFrom;
use std::io::Write;
#[derive(Debug, Default, Clone)]
pub struct Memory;
pub trait Storage: Sized {
type Buffer: Write;
fn create_buffer(&self) -> Result<Self::Buffer, IoError>;
fn write_buffer<W: Write>(&self, buffer: Self::Buffer, file: &mut W) -> Result<(), IoError>;
fn buffer_length(&self, buffer: &Self::Buffer) -> Result<u64, IoError>;
fn close(self) -> Result<(), IoError> {
Ok(())
}
}
#[cfg(feature = "tempfile")]
impl Storage for tempfile::TempDir {
type Buffer = File;
fn create_buffer(&self) -> Result<Self::Buffer, IoError> {
tempfile::tempfile_in(self.path())
}
fn buffer_length(&self, buffer: &Self::Buffer) -> Result<u64, IoError> {
buffer.sync_all()?;
Ok(buffer.metadata()?.len())
}
fn write_buffer<W: Write>(
&self,
mut buffer: Self::Buffer,
file: &mut W,
) -> Result<(), IoError> {
buffer.seek(SeekFrom::Start(0))?;
std::io::copy(&mut buffer, file)?;
Ok(())
}
fn close(self) -> Result<(), IoError> {
tempfile::TempDir::close(self)
}
}
impl Storage for Memory {
type Buffer = Vec<u8>;
fn create_buffer(&self) -> Result<Self::Buffer, IoError> {
Ok(Vec::new())
}
fn buffer_length(&self, buffer: &Self::Buffer) -> Result<u64, IoError> {
Ok(buffer.len() as u64)
}
fn write_buffer<W: Write>(&self, buffer: Self::Buffer, file: &mut W) -> Result<(), IoError> {
file.write_all(buffer.as_slice())
}
}