polaris-mirror/src/vfs.rs
2016-09-22 23:48:27 -07:00

92 lines
2.5 KiB
Rust

use std::collections::HashMap;
use std::path::PathBuf;
use std::path::Path;
use error::*;
pub struct MountDir {
pub name: String,
pub path: PathBuf,
}
impl MountDir {
pub fn new(name: String, path: PathBuf) -> MountDir {
MountDir {
name: name,
path: path,
}
}
}
pub struct Vfs {
mount_points: HashMap<String, PathBuf>,
}
impl Vfs {
pub fn new() -> Vfs {
let instance = Vfs { mount_points: HashMap::new() };
instance
}
pub fn mount(&mut self, name: &str, real_path: &Path) -> Result<(), PError> {
let name = name.to_string();
if self.mount_points.contains_key(&name) {
return Err(PError::ConflictingMount);
}
self.mount_points.insert(name, real_path.to_path_buf());
Ok(())
}
pub fn real_to_virtual(&self, real_path: &Path) -> Result<PathBuf, PError> {
for (name, target) in &self.mount_points {
match real_path.strip_prefix(target) {
Ok(p) => {
let mount_path = Path::new(&name);
return Ok(mount_path.join(p));
}
Err(_) => (),
}
}
Err(PError::PathNotInVfs)
}
pub fn virtual_to_real(&self, virtual_path: &Path) -> Result<PathBuf, PError> {
for (name, target) in &self.mount_points {
let mount_path = Path::new(&name);
match virtual_path.strip_prefix(mount_path) {
Ok(p) => return Ok(target.join(p)),
Err(_) => (),
}
}
Err(PError::PathNotInVfs)
}
pub fn get_mount_points(&self) -> &HashMap<String, PathBuf> {
return &self.mount_points;
}
}
#[test]
fn test_mount() {
let mut vfs = Vfs::new();
assert!(vfs.mount("root", Path::new("test_dir")).is_ok());
assert!(vfs.mount("root", Path::new("another_dir")).is_err());
}
#[test]
fn test_virtual_to_real() {
let mut vfs = Vfs::new();
assert!(vfs.mount("root", Path::new("test_dir")).is_ok());
let correct_path = Path::new("test_dir/somewhere/something.png");
let found_path = vfs.virtual_to_real(Path::new("root/somewhere/something.png")).unwrap();
assert!(found_path == correct_path);
}
#[test]
fn test_real_to_virtual() {
let mut vfs = Vfs::new();
assert!(vfs.mount("root", Path::new("test_dir")).is_ok());
let correct_path = Path::new("root/somewhere/something.png");
let found_path = vfs.real_to_virtual(Path::new("test_dir/somewhere/something.png")).unwrap();
assert!(found_path == correct_path);
}