Use config file to mount directories

This commit is contained in:
Antoine Gersant 2016-08-28 15:53:39 -07:00
parent ac7ffa0909
commit 42895931c8
7 changed files with 119 additions and 2 deletions

9
Cargo.lock generated
View file

@ -6,6 +6,7 @@ dependencies = [
"mount 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"router 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.2.0 (git+https://github.com/servo/rust-url)",
]
@ -233,6 +234,14 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "traitobject"
version = "0.0.1"

View file

@ -15,3 +15,6 @@ rustc-serialize = "0.3"
[dependencies]
router = "*"
mount = "*"
[dependencies]
toml = "0.2"

3
Swine.toml Normal file
View file

@ -0,0 +1,3 @@
[[mount_dirs]]
name = "root"
source = "M:/Music/Genres/Electronic/Glitch"

View file

@ -24,6 +24,10 @@ impl From<SwineError> for IronError {
SwineError::ConflictingMount => IronError::new(err, status::BadRequest),
SwineError::PathNotInVfs => IronError::new(err, status::NotFound),
SwineError::CannotServeDirectory => IronError::new(err, status::BadRequest),
SwineError::ConfigFileOpenError => IronError::new(err, status::InternalServerError),
SwineError::ConfigFileReadError => IronError::new(err, status::InternalServerError),
SwineError::ConfigFileParseError => IronError::new(err, status::InternalServerError),
SwineError::ConfigMountDirsParseError => IronError::new(err, status::InternalServerError),
}
}
}

View file

@ -1,6 +1,9 @@
use std::io::prelude::*;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::path::PathBuf;
use toml;
use vfs::*;
use error::*;
@ -71,11 +74,80 @@ pub struct Collection {
vfs: Vfs,
}
const CONFIG_MOUNT_DIRS : &'static str = "mount_dirs";
const CONFIG_MOUNT_DIR_NAME : &'static str = "name";
const CONFIG_MOUNT_DIR_SOURCE : &'static str = "source";
impl Collection {
pub fn new() -> Collection {
Collection { vfs: Vfs::new() }
}
pub fn load_config(&mut self, config_path: &Path) -> Result<(), SwineError>
{
// Open
let mut config_file = match File::open(config_path) {
Ok(c) => c,
Err(_) => return Err(SwineError::ConfigFileOpenError),
};
// Read
let mut config_file_content = String::new();
match config_file.read_to_string(&mut config_file_content) {
Ok(_) => (),
Err(_) => return Err(SwineError::ConfigFileReadError),
};
// Parse
let parsed_config = toml::Parser::new(config_file_content.as_str()).parse();
let parsed_config = match parsed_config {
Some(c) => c,
None => return Err(SwineError::ConfigFileParseError),
};
// Apply
try!(self.load_config_mount_points(&parsed_config));
Ok(())
}
fn load_config_mount_points(&mut self, config: &toml::Table) -> Result<(), SwineError> {
let mount_dirs = match config.get(CONFIG_MOUNT_DIRS) {
Some(s) => s,
None => return Ok(()),
};
let mount_dirs = match mount_dirs {
&toml::Value::Array(ref a) => a,
_ => return Err(SwineError::ConfigMountDirsParseError),
};
for dir in mount_dirs {
let name = match dir.lookup(CONFIG_MOUNT_DIR_NAME) {
None => return Err(SwineError::ConfigMountDirsParseError),
Some(n) => n,
};
let name = match name.as_str() {
None => return Err(SwineError::ConfigMountDirsParseError),
Some(n) => n,
};
let source = match dir.lookup(CONFIG_MOUNT_DIR_SOURCE) {
None => return Err(SwineError::ConfigMountDirsParseError),
Some(n) => n,
};
let source = match source.as_str() {
None => return Err(SwineError::ConfigMountDirsParseError),
Some(n) => n,
};
let source = PathBuf::from(source);
try!(self.mount(name, source.as_path()));
}
Ok(())
}
pub fn mount(&mut self, name: &str, real_path: &Path) -> Result<(), SwineError> {
self.vfs.mount(name, real_path)
}

View file

@ -9,6 +9,10 @@ pub enum SwineError {
ConflictingMount,
PathNotInVfs,
CannotServeDirectory,
ConfigFileOpenError,
ConfigFileReadError,
ConfigFileParseError,
ConfigMountDirsParseError,
}
impl From<io::Error> for SwineError {
@ -27,6 +31,10 @@ impl error::Error for SwineError {
}
SwineError::PathNotInVfs => "Requested path does not index a mount point",
SwineError::CannotServeDirectory => "Only individual files can be served",
SwineError::ConfigFileOpenError => "Could not open config file",
SwineError::ConfigFileReadError => "Could not read config file",
SwineError::ConfigFileParseError => "Could not parse config file",
SwineError::ConfigMountDirsParseError => "Could not parse mount directories in config file",
}
}
@ -37,6 +45,10 @@ impl error::Error for SwineError {
SwineError::ConflictingMount => None,
SwineError::PathNotInVfs => None,
SwineError::CannotServeDirectory => None,
SwineError::ConfigFileOpenError => None,
SwineError::ConfigFileReadError => None,
SwineError::ConfigFileParseError => None,
SwineError::ConfigMountDirsParseError => None,
}
}
}
@ -55,6 +67,18 @@ impl fmt::Display for SwineError {
SwineError::CannotServeDirectory => {
write!(f, "Only individual files can be served")
}
SwineError::ConfigFileOpenError => {
write!(f, "Could not open config file")
}
SwineError::ConfigFileReadError => {
write!(f, "Could not read config file")
}
SwineError::ConfigFileParseError => {
write!(f, "Could not parse config file")
}
SwineError::ConfigMountDirsParseError => {
write!(f, "Could not parse mount directories in config file")
}
}
}
}

View file

@ -2,6 +2,7 @@ extern crate core;
extern crate iron;
extern crate mount;
extern crate rustc_serialize;
extern crate toml;
extern crate url;
use std::path::Path;
@ -22,7 +23,8 @@ use collection::*;
fn main() {
let mut collection = Collection::new();
collection.mount("root", Path::new("samplemusic/"));
collection.load_config(Path::new("Swine.toml")).unwrap();
let collection = Arc::new(Mutex::new(collection));
let mut mount = Mount::new();