use crate::{Module, ModuleLoader, ModuleResult, ParallelCompiler, ParallelConfig};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub struct McpServer {
compiler: ParallelCompiler,
loader: ModuleLoader,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CompileRequest {
pub modules: Vec<String>,
pub parallel: bool,
pub threads: usize,
pub search_paths: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CompileResponse {
pub success: bool,
pub compiled: Vec<String>,
pub errors: Vec<CompileError>,
pub duration_ms: u64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CompileError {
pub module: String,
pub message: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusRequest {}
#[derive(Debug, Serialize, Deserialize)]
pub struct StatusResponse {
pub version: String,
pub parallel_enabled: bool,
pub threads: usize,
pub cached_modules: Vec<String>,
}
impl McpServer {
pub fn new(config: ParallelConfig) -> Self {
Self {
compiler: ParallelCompiler::new(config),
loader: ModuleLoader::new(),
}
}
pub fn handle_compile(&mut self, request: CompileRequest) -> CompileResponse {
let start = std::time::Instant::now();
let mut compiled = Vec::new();
let mut errors = Vec::new();
for path in &request.search_paths {
self.loader.add_search_path(path);
}
let results = if request.parallel {
self.compile_parallel(request.modules)
} else {
self.compile_sequential(request.modules)
};
for result in results {
match result {
Ok(module) => {
compiled.push(module.name.clone());
self.loader.cache_module(module);
}
Err(e) => {
errors.push(CompileError {
module: "unknown".to_string(),
message: format!("{}", e),
});
}
}
}
let duration_ms = start.elapsed().as_millis() as u64;
CompileResponse {
success: errors.is_empty(),
compiled,
errors,
duration_ms,
}
}
pub fn handle_status(&self, _request: StatusRequest) -> StatusResponse {
StatusResponse {
version: env!("CARGO_PKG_VERSION").to_string(),
parallel_enabled: true,
threads: num_cpus::get(),
cached_modules: self.loader.cached_modules(),
}
}
fn compile_parallel(&self, modules: Vec<String>) -> Vec<ModuleResult<Module>> {
self.compiler.compile_modules_parallel(modules, |name| {
Err(crate::ModuleError::LoadError(
name.to_string(),
"Compilation not yet fully integrated".to_string(),
))
})
}
fn compile_sequential(&self, modules: Vec<String>) -> Vec<ModuleResult<Module>> {
modules
.iter()
.map(|name| {
Err(crate::ModuleError::LoadError(
name.to_string(),
"Compilation not yet fully integrated".to_string(),
))
})
.collect()
}
pub fn get_cached_modules(&self) -> Vec<String> {
self.loader.cached_modules()
}
pub fn clear_cache(&mut self) {
self.loader.clear_cache();
}
}
pub struct McpServerBuilder {
threads: usize,
parallel_modules: bool,
parallel_optimization: bool,
}
impl McpServerBuilder {
pub fn new() -> Self {
Self {
threads: 0,
parallel_modules: true,
parallel_optimization: true,
}
}
pub fn threads(mut self, threads: usize) -> Self {
self.threads = threads;
self
}
pub fn parallel_modules(mut self, enabled: bool) -> Self {
self.parallel_modules = enabled;
self
}
pub fn parallel_optimization(mut self, enabled: bool) -> Self {
self.parallel_optimization = enabled;
self
}
pub fn build(self) -> McpServer {
let config = ParallelConfig::new()
.with_threads(self.threads)
.with_parallel_modules(self.parallel_modules)
.with_parallel_optimization(self.parallel_optimization);
McpServer::new(config)
}
}
impl Default for McpServerBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mcp_server_creation() {
let config = ParallelConfig::new();
let server = McpServer::new(config);
let status = server.handle_status(StatusRequest {});
assert!(status.parallel_enabled);
assert!(status.threads > 0);
}
#[test]
fn test_mcp_server_builder() {
let server = McpServerBuilder::new()
.threads(4)
.parallel_modules(true)
.build();
let cached = server.get_cached_modules();
assert_eq!(cached.len(), 0);
}
#[test]
fn test_compile_request() {
let config = ParallelConfig::new();
let mut server = McpServer::new(config);
let request = CompileRequest {
modules: vec!["Test".to_string()],
parallel: false,
threads: 1,
search_paths: vec![],
};
let response = server.handle_compile(request);
assert_eq!(response.compiled.len(), 0);
assert!(response.duration_ms >= 0);
}
#[test]
fn test_status_request() {
let config = ParallelConfig::new();
let server = McpServer::new(config);
let status = server.handle_status(StatusRequest {});
assert_eq!(status.version, env!("CARGO_PKG_VERSION"));
assert!(status.parallel_enabled);
}
}