Use config file to mount directories
This commit is contained in:
parent
ac7ffa0909
commit
42895931c8
7 changed files with 119 additions and 2 deletions
9
Cargo.lock
generated
9
Cargo.lock
generated
|
@ -6,6 +6,7 @@ dependencies = [
|
||||||
"mount 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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]]
|
[[package]]
|
||||||
name = "traitobject"
|
name = "traitobject"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
|
|
@ -14,4 +14,7 @@ rustc-serialize = "0.3"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
router = "*"
|
router = "*"
|
||||||
mount = "*"
|
mount = "*"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
toml = "0.2"
|
3
Swine.toml
Normal file
3
Swine.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[[mount_dirs]]
|
||||||
|
name = "root"
|
||||||
|
source = "M:/Music/Genres/Electronic/Glitch"
|
|
@ -24,6 +24,10 @@ impl From<SwineError> for IronError {
|
||||||
SwineError::ConflictingMount => IronError::new(err, status::BadRequest),
|
SwineError::ConflictingMount => IronError::new(err, status::BadRequest),
|
||||||
SwineError::PathNotInVfs => IronError::new(err, status::NotFound),
|
SwineError::PathNotInVfs => IronError::new(err, status::NotFound),
|
||||||
SwineError::CannotServeDirectory => IronError::new(err, status::BadRequest),
|
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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use toml;
|
||||||
|
|
||||||
use vfs::*;
|
use vfs::*;
|
||||||
use error::*;
|
use error::*;
|
||||||
|
@ -71,11 +74,80 @@ pub struct Collection {
|
||||||
vfs: Vfs,
|
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 {
|
impl Collection {
|
||||||
pub fn new() -> Collection {
|
pub fn new() -> Collection {
|
||||||
Collection { vfs: Vfs::new() }
|
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> {
|
pub fn mount(&mut self, name: &str, real_path: &Path) -> Result<(), SwineError> {
|
||||||
self.vfs.mount(name, real_path)
|
self.vfs.mount(name, real_path)
|
||||||
}
|
}
|
||||||
|
|
24
src/error.rs
24
src/error.rs
|
@ -9,6 +9,10 @@ pub enum SwineError {
|
||||||
ConflictingMount,
|
ConflictingMount,
|
||||||
PathNotInVfs,
|
PathNotInVfs,
|
||||||
CannotServeDirectory,
|
CannotServeDirectory,
|
||||||
|
ConfigFileOpenError,
|
||||||
|
ConfigFileReadError,
|
||||||
|
ConfigFileParseError,
|
||||||
|
ConfigMountDirsParseError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for SwineError {
|
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::PathNotInVfs => "Requested path does not index a mount point",
|
||||||
SwineError::CannotServeDirectory => "Only individual files can be served",
|
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::ConflictingMount => None,
|
||||||
SwineError::PathNotInVfs => None,
|
SwineError::PathNotInVfs => None,
|
||||||
SwineError::CannotServeDirectory => 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 => {
|
SwineError::CannotServeDirectory => {
|
||||||
write!(f, "Only individual files can be served")
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ extern crate core;
|
||||||
extern crate iron;
|
extern crate iron;
|
||||||
extern crate mount;
|
extern crate mount;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
extern crate toml;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
@ -22,7 +23,8 @@ use collection::*;
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let mut collection = Collection::new();
|
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 collection = Arc::new(Mutex::new(collection));
|
||||||
|
|
||||||
let mut mount = Mount::new();
|
let mut mount = Mount::new();
|
||||||
|
|
Loading…
Add table
Reference in a new issue