mirror of
https://github.com/agersant/polaris
synced 2024-11-10 10:14:12 +00:00
Virtual<->real file system conversions
This commit is contained in:
parent
db0b6d684c
commit
6c81cad85e
4 changed files with 43 additions and 16 deletions
|
@ -19,7 +19,8 @@ impl From<CollectionError> for IronError {
|
|||
match err {
|
||||
CollectionError::Io(e) => IronError::new(e, status::NotFound),
|
||||
CollectionError::PathDecoding => IronError::new(err, status::InternalServerError),
|
||||
CollectionError::ConflictingMount(_) => IronError::new(err, status::BadRequest),
|
||||
CollectionError::ConflictingMount => IronError::new(err, status::BadRequest),
|
||||
CollectionError::PathNotInVfs => IronError::new(err, status::NotFound),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,22 +35,26 @@ impl Collection {
|
|||
impl Collection {
|
||||
pub fn browse(&self, path: &Path) -> Result<Vec<CollectionFile>, CollectionError> {
|
||||
|
||||
let full_path = "samplemusic/".to_string() + path.to_str().unwrap(); // TMP use mount directories
|
||||
let full_path = try!(self.vfs.virtual_to_real(path));
|
||||
let full_path = full_path.to_str().unwrap();
|
||||
println!("Browsing: {}", full_path);
|
||||
|
||||
let mut out = vec![];
|
||||
for file in try!(fs::read_dir(full_path)) {
|
||||
let file = try!(file);
|
||||
let file_meta = try!(file.metadata());
|
||||
let file_path = file.path().to_owned();
|
||||
let file_path = file.path();
|
||||
let file_path = file_path.as_path();
|
||||
if file_meta.is_file() {
|
||||
let path_string = try!(file_path.to_str().ok_or(CollectionError::PathDecoding));
|
||||
let virtual_path = try!(self.vfs.real_to_virtual(file_path));
|
||||
let path_string = try!(virtual_path.to_str().ok_or(CollectionError::PathDecoding));
|
||||
let collection_file = CollectionFile::Song(Song {
|
||||
path: path_string.to_string(),
|
||||
});
|
||||
out.push(collection_file);
|
||||
} else if file_meta.is_dir() {
|
||||
let path_string = try!(file_path.to_str().ok_or(CollectionError::PathDecoding));
|
||||
let virtual_path = try!(self.vfs.real_to_virtual(file_path));
|
||||
let path_string = try!(virtual_path.to_str().ok_or(CollectionError::PathDecoding));
|
||||
let collection_file = CollectionFile::Directory(Directory {
|
||||
path: path_string.to_string(),
|
||||
});
|
||||
|
|
12
src/error.rs
12
src/error.rs
|
@ -7,7 +7,8 @@ pub enum CollectionError
|
|||
{
|
||||
PathDecoding,
|
||||
Io(io::Error),
|
||||
ConflictingMount(String),
|
||||
ConflictingMount,
|
||||
PathNotInVfs,
|
||||
}
|
||||
|
||||
impl From<io::Error> for CollectionError {
|
||||
|
@ -21,7 +22,8 @@ impl error::Error for CollectionError {
|
|||
match *self {
|
||||
CollectionError::Io(ref err) => err.description(),
|
||||
CollectionError::PathDecoding => "Error while decoding a Path as a UTF-8 string",
|
||||
CollectionError::ConflictingMount(_) => "Attempting to mount multiple directories under the same name",
|
||||
CollectionError::ConflictingMount => "Attempting to mount multiple directories under the same name",
|
||||
CollectionError::PathNotInVfs => "Requested path does not index a mount point",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +31,8 @@ impl error::Error for CollectionError {
|
|||
match *self {
|
||||
CollectionError::Io(ref err) => Some(err),
|
||||
CollectionError::PathDecoding => None,
|
||||
CollectionError::ConflictingMount(_) => None,
|
||||
CollectionError::ConflictingMount => None,
|
||||
CollectionError::PathNotInVfs => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +42,8 @@ impl fmt::Display for CollectionError {
|
|||
match *self {
|
||||
CollectionError::Io(ref err) => write!(f, "IO error: {}", err),
|
||||
CollectionError::PathDecoding => write!(f, "Path decoding error"),
|
||||
CollectionError::ConflictingMount(ref name) => write!(f, "Mount point {} already has a target directory", name),
|
||||
CollectionError::ConflictingMount => write!(f, "Mount point already has a target directory"),
|
||||
CollectionError::PathNotInVfs => write!(f, "Requested path does not index a mount point"),
|
||||
}
|
||||
}
|
||||
}
|
32
src/vfs.rs
32
src/vfs.rs
|
@ -10,26 +10,44 @@ pub struct Vfs {
|
|||
|
||||
impl Vfs {
|
||||
pub fn new() -> Vfs {
|
||||
Vfs {
|
||||
let mut instance = Vfs {
|
||||
mount_points: HashMap::new(),
|
||||
}
|
||||
};
|
||||
instance.mount( "root", Path::new("samplemusic") );
|
||||
instance
|
||||
}
|
||||
|
||||
pub fn mount(&mut self, name: &str, real_path: &Path) -> Result<(), CollectionError>
|
||||
{
|
||||
let name = name.to_string();
|
||||
if self.mount_points.contains_key(&name) {
|
||||
return Err(CollectionError::ConflictingMount(name));
|
||||
return Err(CollectionError::ConflictingMount);
|
||||
}
|
||||
self.mount_points.insert(name, real_path.to_path_buf());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn real_to_virtual(&self, real_path: &Path) -> Result<(), CollectionError> {
|
||||
Ok(())
|
||||
pub fn real_to_virtual(&self, real_path: &Path) -> Result<PathBuf, CollectionError> {
|
||||
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(CollectionError::PathNotInVfs)
|
||||
}
|
||||
|
||||
pub fn virtual_to_real(&self, virtual_path: &Path) -> Result<(), CollectionError> {
|
||||
Ok(())
|
||||
pub fn virtual_to_real(&self, virtual_path: &Path) -> Result<PathBuf, CollectionError> {
|
||||
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(CollectionError::PathNotInVfs)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue