// src/main.rs //! Главный модуль сервера Futriix //! //! Точка входа в приложение, инициализирует сервер и запускает его. //! Использует wait-free архитектуру с lock-free структурами данных. mod common; mod server; mod lua_shell; use std::env; use std::fs::OpenOptions; use std::io::Write; use crate::common::FutriixError; /// Функция для логирования в файл fn log_to_file(message: &str) { match OpenOptions::new() .create(true) .append(true) .open("futriix.log") { Ok(mut file) => { let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S%.3f").to_string(); let log_message = format!("[{}] {}\n", timestamp, message); let _ = file.write_all(log_message.as_bytes()); } Err(e) => eprintln!("Failed to write to log file: {}", e), } } /// Простая структура для аргументов командной строки struct Args { config: String, debug: bool, http_port: Option, https_port: Option, host: Option, } /// Простой парсер аргументов командной строки fn parse_args() -> Args { let mut args = Args { config: "config.toml".to_string(), debug: false, http_port: None, https_port: None, host: None, }; let mut iter = env::args().skip(1); while let Some(arg) = iter.next() { match arg.as_str() { "--config" | "-c" => { if let Some(value) = iter.next() { args.config = value; } } "--debug" | "-d" => { args.debug = true; } "--http-port" => { if let Some(value) = iter.next() { if let Ok(port) = value.parse() { args.http_port = Some(port); } } } "--https-port" => { if let Some(value) = iter.next() { if let Ok(port) = value.parse() { args.https_port = Some(port); } } } "--host" => { if let Some(value) = iter.next() { args.host = Some(value); } } _ => { if arg.starts_with("--config=") { args.config = arg.trim_start_matches("--config=").to_string(); } else if arg.starts_with("-c=") { args.config = arg.trim_start_matches("-c=").to_string(); } } } } args } /// Функция для вывода текста с ANSI цветом fn print_colored(text: &str, ansi_color: &str) { println!("{}{}\x1b[0m", ansi_color, text); } /// Конвертация HEX цвета в ANSI escape code fn hex_to_ansi(hex_color: &str) -> String { let hex = hex_color.trim_start_matches('#'); if hex.len() == 6 { if let (Ok(r), Ok(g), Ok(b)) = ( u8::from_str_radix(&hex[0..2], 16), u8::from_str_radix(&hex[2..4], 16), u8::from_str_radix(&hex[4..6], 16), ) { return format!("\x1b[38;2;{};{};{}m", r, g, b); } } "\x1b[38;2;255;255;255m".to_string() } #[tokio::main] async fn main() -> Result<(), FutriixError> { // Инициализация логирования в файл log_to_file("Starting Futriix server"); // Вывод приветственного сообщения с цветом #00bfff перед загрузкой конфигурации let color_code = hex_to_ansi("#00bfff"); println!(); // Добавляем пустую строку перед фразой print_colored("Futriix Database Server", &color_code); print_colored("futriix 3i²(by 26.11.2025)", &color_code); println!(); // Добавляем пустую строку после фразы // Парсим аргументы командной строки let args = parse_args(); let config_path = args.config; let message = format!("Loading configuration from: {}", config_path); println!("{}", message); log_to_file(&message); // Создание и запуск сервера match server::FutriixServer::new(&config_path).await { Ok(server) => { log_to_file("Server created successfully"); if let Err(e) = server.run().await { let error_message = format!("Server error: {}", e); eprintln!("{}", error_message); log_to_file(&error_message); std::process::exit(1); } } Err(e) => { let error_message = format!("Failed to create server: {}", e); eprintln!("{}", error_message); log_to_file(&error_message); std::process::exit(1); } } log_to_file("Futriix server stopped"); Ok(()) }