diff --git a/src/plugin.rs b/src/plugin.rs index 1d03d326..6c2f6246 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -7,5 +7,28 @@ pub enum PluginResult { } pub trait Plugin { - fn transform(item: &VfsItem) -> PluginResult; + fn transform_file(&self, plugins: &PluginChain, vfs_item: &VfsItem) -> PluginResult; +} + +pub struct PluginChain { + plugins: Vec>, +} + +impl PluginChain { + pub fn new(plugins: Vec>) -> PluginChain { + PluginChain { + plugins, + } + } + + pub fn transform_file(&self, vfs_item: &VfsItem) -> Option { + for plugin in &self.plugins { + match plugin.transform_file(self, vfs_item) { + PluginResult::Value(rbx_item) => return rbx_item, + PluginResult::Pass => {}, + } + } + + None + } } diff --git a/src/plugins/default_plugin.rs b/src/plugins/default_plugin.rs index b5beeca6..9026f063 100644 --- a/src/plugins/default_plugin.rs +++ b/src/plugins/default_plugin.rs @@ -1,14 +1,20 @@ use std::collections::HashMap; -use plugin::{Plugin, PluginResult}; +use plugin::{Plugin, PluginChain, PluginResult}; use rbx::{RbxItem, RbxValue}; use vfs::VfsItem; pub struct DefaultPlugin; +impl DefaultPlugin { + pub fn new() -> DefaultPlugin { + DefaultPlugin + } +} + impl Plugin for DefaultPlugin { - fn transform(item: &VfsItem) -> PluginResult { - match item { + fn transform_file(&self, plugins: &PluginChain, vfs_item: &VfsItem) -> PluginResult { + match vfs_item { &VfsItem::File { ref contents, ref name } => { let mut properties = HashMap::new(); @@ -24,13 +30,11 @@ impl Plugin for DefaultPlugin { })) }, &VfsItem::Dir { ref children, ref name } => { - // TODO: call back into plugin list and transform there instead - let mut rbx_children = Vec::new(); for (_, child_item) in children { - match Self::transform(child_item) { - PluginResult::Value(Some(rbx_item)) => { + match plugins.transform_file(child_item) { + Some(rbx_item) => { rbx_children.push(rbx_item); }, _ => {}, diff --git a/src/web.rs b/src/web.rs index 670b0f0c..aa069f6d 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::io::Read; use std::sync::{Arc, Mutex}; use std::thread; @@ -6,13 +5,12 @@ use std::thread; use rouille; use serde; use serde_json; -use regex::Regex; use core::Config; use project::Project; -use vfs::{Vfs, VfsChange, VfsItem}; -use rbx::{RbxItem, RbxValue}; -use plugin::{Plugin, PluginResult}; +use vfs::{Vfs, VfsChange}; +use rbx::RbxItem; +use plugin::PluginChain; use plugins::DefaultPlugin; static MAX_BODY_SIZE: usize = 25 * 1024 * 1025; // 25 MiB @@ -103,6 +101,13 @@ pub fn start(config: Config, project: Project, vfs: Arc>) { let server_id = config.server_id.to_string(); + // Fine, rouille, I'll put things in a 'static Arc... + lazy_static! { + static ref PLUGIN_CHAIN: Arc> = Arc::new(Mutex::new(PluginChain::new(vec![ + Box::new(DefaultPlugin::new()), + ]))); + } + thread::spawn(move || { rouille::start_server(address, move |request| { router!(request, @@ -135,6 +140,8 @@ pub fn start(config: Config, project: Project, vfs: Arc>) { }, (POST) (/read) => { + let plugin_chain = PLUGIN_CHAIN.lock().unwrap(); + let read_request: Vec> = match read_json(&request) { Some(v) => v, None => return rouille::Response::empty_400(), @@ -161,12 +168,7 @@ pub fn start(config: Config, project: Project, vfs: Arc>) { .iter() .map(|item| { match *item { - Some(ref item) => { - match DefaultPlugin::transform(item) { - PluginResult::Value(rbx_item) => rbx_item, - _ => None, - } - }, + Some(ref item) => plugin_chain.transform_file(item), None => None, } })