From 19c102a7e8b931abf61b0fc8fe0573d59e1db63f Mon Sep 17 00:00:00 2001 From: Leo dev Date: Sat, 30 Aug 2025 02:41:39 +0200 Subject: [PATCH] Better structure and logger --- Cargo.lock | 1 + Cargo.toml | 1 + src/lib.rs | 73 +++++++++++++++++++++++++++++++++++++++++++++------ src/loader.rs | 12 ++++++--- src/logger.rs | 25 ++++++++++++++++++ src/macros.rs | 21 +++++++++++++++ src/main.rs | 5 ++-- 7 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 src/logger.rs diff --git a/Cargo.lock b/Cargo.lock index b7ae25c..b0bdcb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1683,6 +1683,7 @@ name = "voxa-server" version = "0.1.0" dependencies = [ "anyhow", + "once_cell", "serde", "serde_json", "wasmtime", diff --git a/Cargo.toml b/Cargo.toml index 297bc4d..9a099bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2024" [dependencies] anyhow = "1.0.99" +once_cell = "1.21.3" serde = { version = "1.0.219", features = ["serde_derive"] } serde_json = "1.0.143" wasmtime = { version = "36.0.2", optional = true } diff --git a/src/lib.rs b/src/lib.rs index e7b76b5..8f554b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, + 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 = 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, 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); + } } diff --git a/src/loader.rs b/src/loader.rs index 0775ae7..ab3f092 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -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 { let engine = Engine::default(); @@ -30,17 +34,17 @@ pub fn load_plugins(arr: &mut Vec, 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(()) diff --git a/src/logger.rs b/src/logger.rs new file mode 100644 index 0000000..ce1c849 --- /dev/null +++ b/src/logger.rs @@ -0,0 +1,25 @@ +use std::fmt::Display; + +pub struct Logger { + name: String, +} + +impl Logger { + pub fn new(name: T) -> Self { + Logger { + name: name.to_string(), + } + } + + pub fn info(&self, message: T) { + println!("\x1b[32mINFO\x1b[0m ({}) › {}", self.name, message); + } + + pub fn warn(&self, message: T) { + println!("\x1b[33mWARN\x1b[0m ({}) › {}", self.name, message); + } + + pub fn error(&self, message: T) { + println!("\x1b[31mERROR\x1b[0m ({}) › {}", self.name, message); + } +} diff --git a/src/macros.rs b/src/macros.rs index 1fc78f2..4fd27ea 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -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) + }; +} diff --git a/src/main.rs b/src/main.rs index b715d6c..028515b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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(()) }