Implement PluginChain

This commit is contained in:
Lucien Greathouse
2017-12-13 23:40:32 -08:00
parent 21e9625c36
commit 01325c8c7e
3 changed files with 48 additions and 19 deletions

View File

@@ -7,5 +7,28 @@ pub enum PluginResult {
} }
pub trait Plugin { pub trait Plugin {
fn transform(item: &VfsItem) -> PluginResult; fn transform_file(&self, plugins: &PluginChain, vfs_item: &VfsItem) -> PluginResult;
}
pub struct PluginChain {
plugins: Vec<Box<Plugin + Send>>,
}
impl PluginChain {
pub fn new(plugins: Vec<Box<Plugin + Send>>) -> PluginChain {
PluginChain {
plugins,
}
}
pub fn transform_file(&self, vfs_item: &VfsItem) -> Option<RbxItem> {
for plugin in &self.plugins {
match plugin.transform_file(self, vfs_item) {
PluginResult::Value(rbx_item) => return rbx_item,
PluginResult::Pass => {},
}
}
None
}
} }

View File

@@ -1,14 +1,20 @@
use std::collections::HashMap; use std::collections::HashMap;
use plugin::{Plugin, PluginResult}; use plugin::{Plugin, PluginChain, PluginResult};
use rbx::{RbxItem, RbxValue}; use rbx::{RbxItem, RbxValue};
use vfs::VfsItem; use vfs::VfsItem;
pub struct DefaultPlugin; pub struct DefaultPlugin;
impl DefaultPlugin {
pub fn new() -> DefaultPlugin {
DefaultPlugin
}
}
impl Plugin for DefaultPlugin { impl Plugin for DefaultPlugin {
fn transform(item: &VfsItem) -> PluginResult { fn transform_file(&self, plugins: &PluginChain, vfs_item: &VfsItem) -> PluginResult {
match item { match vfs_item {
&VfsItem::File { ref contents, ref name } => { &VfsItem::File { ref contents, ref name } => {
let mut properties = HashMap::new(); let mut properties = HashMap::new();
@@ -24,13 +30,11 @@ impl Plugin for DefaultPlugin {
})) }))
}, },
&VfsItem::Dir { ref children, ref name } => { &VfsItem::Dir { ref children, ref name } => {
// TODO: call back into plugin list and transform there instead
let mut rbx_children = Vec::new(); let mut rbx_children = Vec::new();
for (_, child_item) in children { for (_, child_item) in children {
match Self::transform(child_item) { match plugins.transform_file(child_item) {
PluginResult::Value(Some(rbx_item)) => { Some(rbx_item) => {
rbx_children.push(rbx_item); rbx_children.push(rbx_item);
}, },
_ => {}, _ => {},

View File

@@ -1,4 +1,3 @@
use std::collections::HashMap;
use std::io::Read; use std::io::Read;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
@@ -6,13 +5,12 @@ use std::thread;
use rouille; use rouille;
use serde; use serde;
use serde_json; use serde_json;
use regex::Regex;
use core::Config; use core::Config;
use project::Project; use project::Project;
use vfs::{Vfs, VfsChange, VfsItem}; use vfs::{Vfs, VfsChange};
use rbx::{RbxItem, RbxValue}; use rbx::RbxItem;
use plugin::{Plugin, PluginResult}; use plugin::PluginChain;
use plugins::DefaultPlugin; use plugins::DefaultPlugin;
static MAX_BODY_SIZE: usize = 25 * 1024 * 1025; // 25 MiB static MAX_BODY_SIZE: usize = 25 * 1024 * 1025; // 25 MiB
@@ -103,6 +101,13 @@ pub fn start(config: Config, project: Project, vfs: Arc<Mutex<Vfs>>) {
let server_id = config.server_id.to_string(); let server_id = config.server_id.to_string();
// Fine, rouille, I'll put things in a 'static Arc<Mutex>...
lazy_static! {
static ref PLUGIN_CHAIN: Arc<Mutex<PluginChain>> = Arc::new(Mutex::new(PluginChain::new(vec![
Box::new(DefaultPlugin::new()),
])));
}
thread::spawn(move || { thread::spawn(move || {
rouille::start_server(address, move |request| { rouille::start_server(address, move |request| {
router!(request, router!(request,
@@ -135,6 +140,8 @@ pub fn start(config: Config, project: Project, vfs: Arc<Mutex<Vfs>>) {
}, },
(POST) (/read) => { (POST) (/read) => {
let plugin_chain = PLUGIN_CHAIN.lock().unwrap();
let read_request: Vec<Vec<String>> = match read_json(&request) { let read_request: Vec<Vec<String>> = match read_json(&request) {
Some(v) => v, Some(v) => v,
None => return rouille::Response::empty_400(), None => return rouille::Response::empty_400(),
@@ -161,12 +168,7 @@ pub fn start(config: Config, project: Project, vfs: Arc<Mutex<Vfs>>) {
.iter() .iter()
.map(|item| { .map(|item| {
match *item { match *item {
Some(ref item) => { Some(ref item) => plugin_chain.transform_file(item),
match DefaultPlugin::transform(item) {
PluginResult::Value(rbx_item) => rbx_item,
_ => None,
}
},
None => None, None => None,
} }
}) })