vmbfs/
single_file_backing.rsuse crate::backing::FileError;
use crate::backing::FileInfo;
use crate::backing::VmbfsIo;
use inspect::InspectMut;
use std::fs::File;
use std::io::Read;
use std::io::Seek;
use thiserror::Error;
#[derive(InspectMut)]
pub struct VmbfsSingleFileBacking {
path: String,
file: File,
}
#[derive(Debug, Error)]
#[error("invalid path")]
pub struct InvalidFileName;
impl VmbfsSingleFileBacking {
pub fn new(name: &str, file: File) -> Result<Self, InvalidFileName> {
if name.contains('/') || name.contains('\\') {
return Err(InvalidFileName);
}
let path = format!("/{name}");
Ok(Self { path, file })
}
}
impl VmbfsIo for VmbfsSingleFileBacking {
fn file_info(&mut self, path: &str) -> Result<FileInfo, FileError> {
if path != self.path {
return Err(FileError::NotFound);
}
let metadata = self.file.metadata()?;
Ok(FileInfo {
directory: false,
file_size: metadata.len(),
})
}
fn read_file(&mut self, path: &str, offset: u64, buf: &mut [u8]) -> Result<(), FileError> {
if path != self.path {
return Err(FileError::NotFound);
}
self.file.seek(std::io::SeekFrom::Start(offset))?;
self.file.read_exact(buf)?;
Ok(())
}
}