diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 50d3cf3..0000000 --- a/src/main.rs +++ /dev/null @@ -1,278 +0,0 @@ -// src/main.rs -//! Главный модуль сервера Futriix -//! -//! Точка входа в приложение, инициализирует сервер и запускает его. -//! Использует wait-free архитектуру с lock-free структурами данных. -//! -//! Особенности: -//! - Логирование в файл с временными метками и миллисекундами -//! - Парсинг аргументов командной строки -//! - Цветной вывод с поддержкой ANSI кодов -//! - Инициализация и запуск сервера -//! - Обработка ошибок и graceful shutdown - -mod common; // Модуль общих утилит и типов ошибок -mod server; // Основной модуль сервера -mod lua_shell; // Интерактивная Lua оболочка - -use std::env; // Работа с переменными окружения -use std::fs::OpenOptions; // Открытие файлов с различными опциями -use std::io::Write; // Запись в файлы - -use crate::common::FutriixError; // Основной тип ошибки системы - -/// Функция для логирования в файл -/// Записывает сообщения в файл futriix.log с временными метками -/// Используется для отладки и аудита работы сервера -/// -/// # Аргументы -/// * `message` - Сообщение для записи в лог -/// -/// # Пример использования -/// ```rust -/// log_to_file("Сервер запускается"); -/// ``` -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), - } -} - -/// Структура для хранения аргументов командной строки -/// Содержит параметры конфигурации и флаги отладки -/// -/// # Поля -/// * `config` - Путь к файлу конфигурации -/// * `debug` - Флаг режима отладки -/// * `http_port` - Порт HTTP сервера (опционально) -/// * `https_port` - Порт HTTPS сервера (опционально) -/// * `host` - Хост для привязки сервера (опционально) -struct Args { - config: String, // Путь к файлу конфигурации - debug: bool, // Флаг режима отладки - http_port: Option, // Порт HTTP сервера (опционально) - https_port: Option,// Порт HTTPS сервера (опционально) - host: Option, // Хост для привязки сервера (опционально) -} - -/// Парсер аргументов командной строки -/// Поддерживает короткие и длинные формы аргументов -/// Возвращает структуру Args с распарсенными значениями -/// -/// # Поддерживаемые аргументы -/// * `--config`, `-c` - Путь к файлу конфигурации -/// * `--debug`, `-d` - Включение режима отладки -/// * `--http-port` - Порт HTTP сервера -/// * `--https-port` - Порт HTTPS сервера -/// * `--host` - Хост для привязки сервера -/// -/// # Пример использования -/// ```bash -/// futriix --config my_config.toml --debug --http-port 8080 -/// ``` -fn parse_args() -> Args { - // Инициализируем структуру со значениями по умолчанию - let mut args = Args { - config: "config.toml".to_string(), // Конфигурация по умолчанию - debug: false, // Режим отладки выключен по умолчанию - http_port: None, // Порт HTTP не задан - https_port: None, // Порт HTTPS не задан - 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 сервера - "--http-port" => { - if let Some(value) = iter.next() { - if let Ok(port) = value.parse() { - args.http_port = Some(port); - } - } - } - // Установка порта HTTPS сервера - "--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=") { - // Формат: --config=путь/к/конфигурации.toml - args.config = arg.trim_start_matches("--config=").to_string(); - } else if arg.starts_with("-c=") { - // Формат: -c=путь/к/конфигурации.toml - args.config = arg.trim_start_matches("-c=").to_string(); - } - // Неизвестные аргументы игнорируются - } - } - } - - args -} - -/// Функция для вывода текста с ANSI цветом -/// Использует escape-последовательности для цветного форматирования -/// Параметр ansi_color должен содержать ANSI escape code -/// -/// # Аргументы -/// * `text` - Текст для вывода -/// * `ansi_color` - ANSI escape code для установки цвета -/// -/// # Пример использования -/// ```rust -/// print_colored("Hello World!", "\x1b[38;2;255;0;0m"); -/// ``` -fn print_colored(text: &str, ansi_color: &str) { - // Выводим цветной текст и сбрасываем цвет в конце - println!("{}{}\x1b[0m", ansi_color, text); -} - -/// Конвертация HEX цвета в ANSI escape code -/// Принимает строку в формате #RRGGBB или RRGGBB -/// Возвращает ANSI escape sequence для установки цвета текста -/// -/// # Аргументы -/// * `hex_color` - HEX цвет в формате #RRGGBB или RRGGBB -/// -/// # Возвращаемое значение -/// * `String` - ANSI escape sequence для установки цвета -/// -/// # Пример использования -/// ```rust -/// let ansi_color = hex_to_ansi("#00bfff"); // Голубой цвет -/// ``` -fn hex_to_ansi(hex_color: &str) -> String { - // Убираем символ # если он есть - let hex = hex_color.trim_start_matches('#'); - - // Проверяем, что строка имеет правильную длину (6 символов для RRGGBB) - if hex.len() == 6 { - // Парсим компоненты цвета: красный, зеленый, синий - if let (Ok(r), Ok(g), Ok(b)) = ( - u8::from_str_radix(&hex[0..2], 16), // Красный (первые 2 символа) - u8::from_str_radix(&hex[2..4], 16), // Зеленый (следующие 2 символа) - u8::from_str_radix(&hex[4..6], 16), // Синий (последние 2 символа) - ) { - // Формируем ANSI escape sequence для установки RGB цвета - return format!("\x1b[38;2;{};{};{}m", r, g, b); - } - } - - // В случае ошибки парсинга возвращаем белый цвет по умолчанию - "\x1b[38;2;255;255;255m".to_string() -} - -/// Точка входа в приложение Futriix -/// Инициализирует сервер, парсит аргументы командной строки и запускает систему -/// -/// # Возвращаемое значение -/// * `Result<(), FutriixError>` - Результат выполнения, содержащий ошибку если что-то пошло не так -/// -/// # Пример использования -/// ```bash -/// cargo run -- --config my_config.toml -/// ``` -#[tokio::main] -async fn main() -> Result<(), FutriixError> { - // Инициализация логирования в файл - // Записываем стартовое сообщение в лог - log_to_file("Starting Futriix server"); - - // Вывод приветственного сообщения с цветом #00bfff перед загрузкой конфигурации - // Используем голубой цвет для брендинга Futriix - 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); - - // Создание и запуск сервера с использованием async/await - 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); - - // Завершаем процесс с кодом ошибки 1 - std::process::exit(1); - } - } - Err(e) => { - // Обрабатываем ошибку создания сервера - let error_message = format!("Failed to create server: {}", e); - eprintln!("{}", error_message); - log_to_file(&error_message); - - // Завершаем процесс с кодом ошибки 1 - std::process::exit(1); - } - } - - // Логируем завершение работы сервера - log_to_file("Futriix server stopped"); - - // Успешное завершение программы - Ok(()) -}