pub mod cli;
pub mod commands;
pub mod completion;
pub mod config;
pub mod constants;
pub mod errors;
pub mod file_utils;
pub mod output;
pub mod progress;
pub mod scheduler;
pub mod utils;
use crate::cli::Cli;
use clap::Parser;
use colored::Colorize;
use commands::{Command, Commands, OutputFormat};
use config::{Config, UnifiedConfigAdapter};
use constants::{exit_codes, ui::emoji};
use errors::prelude::Result as CliResult;
use std::path::Path;
use std::process::exit;
use tracing::debug;
use utils::{create_bot_instance, create_dummy_bot, needs_bot_instance};
use vkteams_bot::otlp;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
let _guard = otlp::init()?;
let cli = Cli::parse();
if cli.verbose {
unsafe {
std::env::set_var("RUST_LOG", "debug");
}
}
let config = match load_configuration(&cli) {
Ok(config) => config,
Err(err) => {
eprintln!(
"{} {}",
emoji::CROSS,
format!("Failed to load configuration: {err}").red()
);
exit(exit_codes::CONFIG);
}
};
if let Some(path) = &cli.save_config {
if let Err(err) = save_configuration(&config, path) {
eprintln!(
"{} {}",
emoji::CROSS,
format!("Failed to save configuration: {err}").red()
);
exit(exit_codes::CONFIG);
}
println!(
"{} Configuration saved to: {}",
emoji::FLOPPY_DISK,
path.green()
);
return Ok(());
}
debug!("Configuration loaded");
if let Err(err) = cli.command.validate() {
eprintln!(
"{} {}",
emoji::CROSS,
format!("Validation error: {err}").red()
);
exit(exit_codes::USAGE_ERROR);
}
match execute_command(&cli.command, &config, &cli.output).await {
Ok(()) => {
debug!("Command executed successfully");
}
Err(err) => {
eprintln!("{} {}", emoji::CROSS, format!("Error: {err}").red());
exit(err.exit_code());
}
}
Ok(())
}
fn load_configuration(cli: &Cli) -> CliResult<Config> {
if let Some(config_path) = &cli.config {
UnifiedConfigAdapter::load_from_path(Path::new(config_path))
} else {
UnifiedConfigAdapter::load()
}
}
fn save_configuration(config: &Config, path: &str) -> CliResult<()> {
config.save(Some(Path::new(path)))
}
async fn execute_command(
command: &Commands,
config: &Config,
output_format: &OutputFormat,
) -> CliResult<()> {
let bot = if needs_bot_instance(command) {
create_bot_instance(config)?
} else {
create_dummy_bot()
};
match command {
Commands::Files(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Storage(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Messaging(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Chat(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Daemon(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Diagnostic(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Config(cmd) => cmd.execute_with_output(&bot, output_format).await,
Commands::Scheduling(cmd) => cmd.execute_with_output(&bot, output_format).await,
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_main_runs() {
}
}