Prototype plugin architecture, switch instance-based stuff to that

This commit is contained in:
Lucien Greathouse
2017-12-13 17:50:34 -08:00
parent 5bf1f11190
commit 21e9625c36
7 changed files with 99 additions and 88 deletions

View File

@@ -22,6 +22,9 @@ pub mod project;
pub mod pathext;
pub mod vfs;
pub mod vfs_watch;
pub mod rbx;
pub mod plugin;
pub mod plugins;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};

11
src/plugin.rs Normal file
View File

@@ -0,0 +1,11 @@
use rbx::RbxItem;
use vfs::VfsItem;
pub enum PluginResult {
Value(Option<RbxItem>),
Pass,
}
pub trait Plugin {
fn transform(item: &VfsItem) -> PluginResult;
}

View File

@@ -0,0 +1,49 @@
use std::collections::HashMap;
use plugin::{Plugin, PluginResult};
use rbx::{RbxItem, RbxValue};
use vfs::VfsItem;
pub struct DefaultPlugin;
impl Plugin for DefaultPlugin {
fn transform(item: &VfsItem) -> PluginResult {
match item {
&VfsItem::File { ref contents, ref name } => {
let mut properties = HashMap::new();
properties.insert("Value".to_string(), RbxValue::String {
value: contents.clone(),
});
PluginResult::Value(Some(RbxItem {
name: name.clone(),
class_name: "StringValue".to_string(),
children: Vec::new(),
properties,
}))
},
&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)) => {
rbx_children.push(rbx_item);
},
_ => {},
}
}
PluginResult::Value(Some(RbxItem {
name: name.clone(),
class_name: "Folder".to_string(),
children: rbx_children,
properties: HashMap::new(),
}))
},
}
}
}

3
src/plugins/mod.rs Normal file
View File

@@ -0,0 +1,3 @@
mod default_plugin;
pub use self::default_plugin::*;

18
src/rbx.rs Normal file
View File

@@ -0,0 +1,18 @@
use std::collections::HashMap;
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RbxItem {
pub name: String,
pub class_name: String,
pub children: Vec<RbxItem>,
pub properties: HashMap<String, RbxValue>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum RbxValue {
String {
value: String,
},
}

View File

@@ -37,8 +37,8 @@ pub struct VfsChange {
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum VfsItem {
File { contents: String },
Dir { children: HashMap<String, VfsItem> },
File { name: String, contents: String },
Dir { name: String, children: HashMap<String, VfsItem> },
}
impl Vfs {
@@ -78,6 +78,7 @@ impl Vfs {
}
fn read_dir<P: AsRef<Path>>(&self, path: P) -> Result<VfsItem, ()> {
let path = path.as_ref();
let reader = match fs::read_dir(path) {
Ok(v) => v,
Err(_) => return Err(()),
@@ -104,11 +105,13 @@ impl Vfs {
}
Ok(VfsItem::Dir {
name: path.file_name().unwrap().to_string_lossy().into_owned(),
children,
})
}
fn read_file<P: AsRef<Path>>(&self, path: P) -> Result<VfsItem, ()> {
let path = path.as_ref();
let mut file = match File::open(path) {
Ok(v) => v,
Err(_) => return Err(()),
@@ -122,6 +125,7 @@ impl Vfs {
}
Ok(VfsItem::File {
name: path.file_name().unwrap().to_string_lossy().into_owned(),
contents,
})
}

View File

@@ -11,94 +11,12 @@ use regex::Regex;
use core::Config;
use project::Project;
use vfs::{Vfs, VfsChange, VfsItem};
use rbx::{RbxItem, RbxValue};
use plugin::{Plugin, PluginResult};
use plugins::DefaultPlugin;
static MAX_BODY_SIZE: usize = 25 * 1024 * 1025; // 25 MiB
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct RbxItem {
name: String,
class_name: String,
children: Vec<RbxItem>,
properties: HashMap<String, RbxValue>,
}
impl RbxItem {
pub fn from_vfs_item(file_name: &String, item: &VfsItem) -> RbxItem {
lazy_static! {
static ref PT_MODULE: Regex = Regex::new(r"^(.*?)\.lua$").unwrap();
}
match item {
&VfsItem::File { ref contents } => {
let mut properties = HashMap::new();
properties.insert("Source".to_string(), RbxValue::String {
value: contents.clone()
});
let rbx_name = {
if let Some(captures) = PT_MODULE.captures(file_name) {
captures.get(1).unwrap().as_str().to_string()
} else {
file_name.clone()
}
};
RbxItem {
name: rbx_name,
class_name: "ModuleScript".to_string(),
children: Vec::new(),
properties,
}
},
&VfsItem::Dir { ref children } => {
let init = children.get(&"init.lua".to_string());
if let Some(init) = init {
let mut rbx_children = Vec::new();
for (name, child_item) in children {
if name != "init.lua" {
rbx_children.push(RbxItem::from_vfs_item(&name, &child_item));
}
}
let init_rbx = RbxItem::from_vfs_item(&"init.lua".to_string(), &init);
RbxItem {
name: file_name.clone(),
class_name: init_rbx.class_name,
children: rbx_children,
properties: init_rbx.properties,
}
} else {
let mut rbx_children = Vec::new();
for (name, child_item) in children {
rbx_children.push(RbxItem::from_vfs_item(&name, &child_item));
}
RbxItem {
name: file_name.clone(),
class_name: "Folder".to_string(),
children: rbx_children,
properties: HashMap::new(),
}
}
},
}
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase", tag = "type")]
enum RbxValue {
String {
value: String,
},
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
struct ServerInfo<'a> {
@@ -243,7 +161,12 @@ pub fn start(config: Config, project: Project, vfs: Arc<Mutex<Vfs>>) {
.iter()
.map(|item| {
match *item {
Some(ref item) => Some(RbxItem::from_vfs_item(&"src".to_string(), item)),
Some(ref item) => {
match DefaultPlugin::transform(item) {
PluginResult::Value(rbx_item) => rbx_item,
_ => None,
}
},
None => None,
}
})