Better structure and logger
This commit is contained in:
+65
-8
@@ -1,7 +1,11 @@
|
||||
use std::path::Path;
|
||||
use std::{
|
||||
net::TcpListener,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
#[cfg(feature = "loader")]
|
||||
pub mod loader;
|
||||
pub mod logger;
|
||||
pub mod macros;
|
||||
pub mod plugin;
|
||||
pub mod vfs;
|
||||
@@ -15,6 +19,13 @@ pub struct ServerConfig {
|
||||
port: u16,
|
||||
}
|
||||
|
||||
pub struct Server {
|
||||
plugins: Vec<PluginInstance>,
|
||||
root: PathBuf,
|
||||
config: ServerConfig,
|
||||
logger: logger::Logger,
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
fn default() -> Self {
|
||||
Self { port: 7080 }
|
||||
@@ -22,19 +33,65 @@ impl Default for ServerConfig {
|
||||
}
|
||||
|
||||
impl ServerConfig {
|
||||
pub fn start(&self, root: &Path) -> Result<()> {
|
||||
let mut plugins: Vec<PluginInstance> = Vec::new();
|
||||
#[cfg(feature = "loader")]
|
||||
loader::load_plugins(&mut plugins, &root.join("./plugins"))?;
|
||||
pub fn build(self, root: &Path) -> Server {
|
||||
Server::new_config(root, self)
|
||||
}
|
||||
}
|
||||
|
||||
self.start_with(plugins, root)
|
||||
impl Server {
|
||||
pub fn new(root: &Path) -> Self {
|
||||
Self {
|
||||
plugins: Vec::new(),
|
||||
root: root.to_path_buf(),
|
||||
config: ServerConfig::default(),
|
||||
logger: logger::Logger::new("Server"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start_with(&self, mut plugins: Vec<PluginInstance>, root: &Path) -> Result<()> {
|
||||
for plugin in &mut plugins {
|
||||
pub fn new_config(root: &Path, config: ServerConfig) -> Self {
|
||||
Self {
|
||||
plugins: Vec::new(),
|
||||
root: root.to_path_buf(),
|
||||
config,
|
||||
logger: logger::Logger::new("Server"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&mut self) -> Result<()> {
|
||||
// Load plugins
|
||||
#[cfg(feature = "loader")]
|
||||
loader::load_plugins(&mut self.plugins, &self.root.join("./plugins"))?;
|
||||
|
||||
// Initialize plugins
|
||||
for plugin in &mut self.plugins {
|
||||
plugin.init();
|
||||
}
|
||||
|
||||
// Start server
|
||||
let listener = TcpListener::bind(format!("0.0.0.0:{}", self.config.port));
|
||||
self.logger
|
||||
.info(format!("Server listening 0.0.0.0:{}", self.config.port));
|
||||
self.logger
|
||||
.warn(format!("Server listening 0.0.0.0:{}", self.config.port));
|
||||
self.logger
|
||||
.error(format!("Server listening 0.0.0.0:{}", self.config.port));
|
||||
|
||||
for stream in listener?.incoming() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
self.logger
|
||||
.info(format!("New connection: {}", stream.peer_addr()?));
|
||||
}
|
||||
Err(e) => {
|
||||
self.logger.error(format!("Connection failed: {}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_plugin(&mut self, plugin: PluginInstance) {
|
||||
self.plugins.push(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-4
@@ -3,7 +3,11 @@ use std::path::Path;
|
||||
use wasmtime::{Engine, Linker, Module, Store};
|
||||
use wasmtime_wasi::WasiCtxBuilder;
|
||||
|
||||
use crate::{PluginInstance, vfs};
|
||||
use crate::{PluginInstance, logger, vfs};
|
||||
|
||||
logger! {
|
||||
const LOGGER "Loader"
|
||||
}
|
||||
|
||||
pub fn load_plugin(wasm_path: &Path) -> anyhow::Result<PluginInstance> {
|
||||
let engine = Engine::default();
|
||||
@@ -30,17 +34,17 @@ pub fn load_plugins(arr: &mut Vec<PluginInstance>, path: &Path) -> crate::Result
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
if path.extension().and_then(|s| s.to_str()) == Some("wasm") {
|
||||
println!("Loading plugin: {:?}", path);
|
||||
LOGGER.info(format!("Loading plugin: {:?}", path));
|
||||
match load_plugin(&path) {
|
||||
Ok(plugin) => {
|
||||
arr.push(plugin);
|
||||
}
|
||||
Err(e) => eprintln!("Failed to load plugin {:?}: {}", path, e),
|
||||
Err(e) => LOGGER.error(format!("Failed to load plugin {:?}: {}", path, e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintln!("{:?} is not a directory", path);
|
||||
LOGGER.error(format!("{:?} is not a directory", path));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
pub struct Logger {
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Logger {
|
||||
pub fn new<T: Display>(name: T) -> Self {
|
||||
Logger {
|
||||
name: name.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn info<T: Display>(&self, message: T) {
|
||||
println!("\x1b[32mINFO\x1b[0m ({}) › {}", self.name, message);
|
||||
}
|
||||
|
||||
pub fn warn<T: Display>(&self, message: T) {
|
||||
println!("\x1b[33mWARN\x1b[0m ({}) › {}", self.name, message);
|
||||
}
|
||||
|
||||
pub fn error<T: Display>(&self, message: T) {
|
||||
println!("\x1b[31mERROR\x1b[0m ({}) › {}", self.name, message);
|
||||
}
|
||||
}
|
||||
@@ -13,3 +13,24 @@ macro_rules! export_plugin {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! logger {
|
||||
(const $i:ident $name:expr) => {
|
||||
const $i: once_cell::sync::Lazy<$crate::logger::Logger> =
|
||||
once_cell::sync::Lazy::new(|| $crate::logger::Logger::new($name));
|
||||
};
|
||||
|
||||
($i:ident $name:expr) => {
|
||||
const $i: once_cell::sync::Lazy<$crate::logger::Logger> =
|
||||
once_cell::sync::Lazy::new(|| $crate::logger::Logger::new($name));
|
||||
};
|
||||
|
||||
(const $name:expr) => {
|
||||
once_cell::sync::Lazy::new(|| $crate::logger::Logger::new($name))
|
||||
};
|
||||
|
||||
($name:expr) => {
|
||||
$crate::logger::Logger::new($name)
|
||||
};
|
||||
}
|
||||
|
||||
+3
-2
@@ -5,6 +5,7 @@ use voxa_server::{ServerConfig, vfs};
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let root = PathBuf::new();
|
||||
let config: ServerConfig = vfs::read_config(&root.join("config.json"))?;
|
||||
|
||||
config.start(&root)
|
||||
let mut server = config.build(&root);
|
||||
server.run()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user