use crate::config::Config;
use crate::server::HttpServer;
use crate::utils::error::gateway_error::{GatewayError, Result};
use tracing::info;
pub struct ServerBuilder {
config: Option<Config>,
}
impl ServerBuilder {
pub fn new() -> Self {
Self { config: None }
}
pub fn with_config(mut self, config: Config) -> Self {
self.config = Some(config);
self
}
pub async fn build(self) -> Result<HttpServer> {
let config = self
.config
.ok_or_else(|| GatewayError::Config("Configuration is required".to_string()))?;
HttpServer::new(&config).await
}
}
impl Default for ServerBuilder {
fn default() -> Self {
Self::new()
}
}
pub async fn run_server() -> Result<()> {
info!("🚀 Starting Rust LiteLLM Gateway");
let config_path = "config/gateway.yaml";
info!("📄 Loading configuration file: {}", config_path);
let config = match Config::from_file(config_path).await {
Ok(config) => {
info!("✅ Configuration file loaded successfully");
config
}
Err(file_error) => {
info!(
"⚠️ Failed to load {}: {}. Trying environment variables.",
config_path, file_error
);
match Config::from_env() {
Ok(config) => {
info!("✅ Loaded configuration from environment variables");
config
}
Err(env_error) => {
return Err(GatewayError::Config(format!(
"Failed to load configuration from file ({}) and environment ({}).",
file_error, env_error
)));
}
}
}
};
config.validate()?;
let server = HttpServer::new(&config).await?;
info!(
"🌐 Server starting at: http://{}:{}",
config.server().host,
config.server().port
);
info!("📋 API Endpoints:");
info!(" GET /health - Health check");
info!(" GET /v1/models - Model list");
info!(" POST /v1/chat/completions - Chat completions");
info!(" POST /v1/embeddings - Text embeddings");
server.start().await
}