diff --git a/src/lib.rs b/src/lib.rs index d6c7289..e8876fa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +use std::path::Path; + #[cfg(feature = "loader")] use wasmtime::{Instance, Store}; #[cfg(feature = "loader")] @@ -6,6 +8,7 @@ use wasmtime_wasi::preview1::WasiP1Ctx; #[cfg(feature = "loader")] pub mod loader; pub mod macros; +pub mod vfs; pub use anyhow::Result; @@ -37,15 +40,15 @@ impl PluginApi for PluginInstance { } impl ServerConfig { - pub fn start(&self) -> Result<()> { + pub fn start(&self, root: &Path) -> Result<()> { let mut plugins: Vec = Vec::new(); #[cfg(feature = "loader")] - loader::load_plugins(&mut plugins, std::path::Path::new("./plugins")); + loader::load_plugins(&mut plugins, &root.join("./plugins"))?; - self.start_with(plugins) + self.start_with(plugins, root) } - pub fn start_with(&self, mut plugins: Vec) -> Result<()> { + pub fn start_with(&self, mut plugins: Vec, root: &Path) -> Result<()> { for plugin in &mut plugins { plugin.init(); } diff --git a/src/loader.rs b/src/loader.rs index 4c51ce8..5e66b69 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -3,9 +3,9 @@ use std::path::Path; use wasmtime::*; use wasmtime_wasi::WasiCtxBuilder; -use crate::PluginInstance; +use crate::{PluginInstance, vfs}; -pub fn load_plugin(wasm_path: &str) -> anyhow::Result { +pub fn load_plugin(wasm_path: &Path) -> anyhow::Result { let engine = Engine::default(); let mut store = Store::new( &engine, @@ -23,14 +23,15 @@ pub fn load_plugin(wasm_path: &str) -> anyhow::Result { Ok(PluginInstance::Wasm(instance, store)) } -pub fn load_plugins(arr: &mut Vec, path: &Path) { +pub fn load_plugins(arr: &mut Vec, path: &Path) -> crate::Result<()> { + vfs::dir(path)?; if path.is_dir() { - for entry in std::fs::read_dir(path).unwrap() { - let entry = entry.unwrap(); + for entry in std::fs::read_dir(path)? { + let entry = entry?; let path = entry.path(); if path.extension().and_then(|s| s.to_str()) == Some("wasm") { println!("Loading plugin: {:?}", path); - match load_plugin(path.to_str().unwrap()) { + match load_plugin(&path) { Ok(plugin) => { arr.push(plugin); } @@ -41,4 +42,6 @@ pub fn load_plugins(arr: &mut Vec, path: &Path) { } else { eprintln!("{:?} is not a directory", path); } + + Ok(()) } diff --git a/src/main.rs b/src/main.rs index 9ccfd8d..b3a7593 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ +use std::path::PathBuf; + fn main() -> anyhow::Result<()> { + let root = PathBuf::new(); let config = voxa_server::ServerConfig::default(); - config.start() + config.start(&root) } diff --git a/src/vfs.rs b/src/vfs.rs new file mode 100644 index 0000000..35c287f --- /dev/null +++ b/src/vfs.rs @@ -0,0 +1,34 @@ +use std::{fs, path::Path}; + +pub fn dir(path: &Path) -> crate::Result<()> { + if !path.exists() { + fs::create_dir_all(path)?; + } + Ok(()) +} + +pub fn read(path: &Path, default_content: &str) -> crate::Result { + if !path.exists() { + dir(path.parent().ok_or(std::io::Error::new( + std::io::ErrorKind::InvalidFilename, + "File doesn't have a parent assigned, example: `config/config.json`", + ))?)?; + fs::write(path, default_content)?; + return Ok(default_content.to_string()); + } + + Ok(fs::read_to_string(path)?) +} + +pub fn read_bytes<'a>(path: &Path, default_content: Vec) -> crate::Result> { + if !path.exists() { + dir(path.parent().ok_or(std::io::Error::new( + std::io::ErrorKind::InvalidFilename, + "File doesn't have a parent assigned, example: `config/config.json`", + ))?)?; + fs::write(path, &default_content)?; + return Ok(default_content); + } + + Ok(fs::read(path)?) +}