mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-25 15:16:07 +00:00
Prototype plugin architecture, switch instance-based stuff to that
This commit is contained in:
@@ -22,6 +22,9 @@ pub mod project;
|
|||||||
pub mod pathext;
|
pub mod pathext;
|
||||||
pub mod vfs;
|
pub mod vfs;
|
||||||
pub mod vfs_watch;
|
pub mod vfs_watch;
|
||||||
|
pub mod rbx;
|
||||||
|
pub mod plugin;
|
||||||
|
pub mod plugins;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|||||||
11
src/plugin.rs
Normal file
11
src/plugin.rs
Normal 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;
|
||||||
|
}
|
||||||
49
src/plugins/default_plugin.rs
Normal file
49
src/plugins/default_plugin.rs
Normal 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
3
src/plugins/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
mod default_plugin;
|
||||||
|
|
||||||
|
pub use self::default_plugin::*;
|
||||||
18
src/rbx.rs
Normal file
18
src/rbx.rs
Normal 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,
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -37,8 +37,8 @@ pub struct VfsChange {
|
|||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase", tag = "type")]
|
#[serde(rename_all = "camelCase", tag = "type")]
|
||||||
pub enum VfsItem {
|
pub enum VfsItem {
|
||||||
File { contents: String },
|
File { name: String, contents: String },
|
||||||
Dir { children: HashMap<String, VfsItem> },
|
Dir { name: String, children: HashMap<String, VfsItem> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vfs {
|
impl Vfs {
|
||||||
@@ -78,6 +78,7 @@ impl Vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_dir<P: AsRef<Path>>(&self, path: P) -> Result<VfsItem, ()> {
|
fn read_dir<P: AsRef<Path>>(&self, path: P) -> Result<VfsItem, ()> {
|
||||||
|
let path = path.as_ref();
|
||||||
let reader = match fs::read_dir(path) {
|
let reader = match fs::read_dir(path) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => return Err(()),
|
Err(_) => return Err(()),
|
||||||
@@ -104,11 +105,13 @@ impl Vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(VfsItem::Dir {
|
Ok(VfsItem::Dir {
|
||||||
|
name: path.file_name().unwrap().to_string_lossy().into_owned(),
|
||||||
children,
|
children,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_file<P: AsRef<Path>>(&self, path: P) -> Result<VfsItem, ()> {
|
fn read_file<P: AsRef<Path>>(&self, path: P) -> Result<VfsItem, ()> {
|
||||||
|
let path = path.as_ref();
|
||||||
let mut file = match File::open(path) {
|
let mut file = match File::open(path) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(_) => return Err(()),
|
Err(_) => return Err(()),
|
||||||
@@ -122,6 +125,7 @@ impl Vfs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(VfsItem::File {
|
Ok(VfsItem::File {
|
||||||
|
name: path.file_name().unwrap().to_string_lossy().into_owned(),
|
||||||
contents,
|
contents,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
95
src/web.rs
95
src/web.rs
@@ -11,94 +11,12 @@ use regex::Regex;
|
|||||||
use core::Config;
|
use core::Config;
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use vfs::{Vfs, VfsChange, VfsItem};
|
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
|
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)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct ServerInfo<'a> {
|
struct ServerInfo<'a> {
|
||||||
@@ -243,7 +161,12 @@ 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(RbxItem::from_vfs_item(&"src".to_string(), item)),
|
Some(ref item) => {
|
||||||
|
match DefaultPlugin::transform(item) {
|
||||||
|
PluginResult::Value(rbx_item) => rbx_item,
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
},
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user