use std::{env, fs}; use std::collections::HashMap; use std::net::Ipv4Addr; use std::path::Path; use log::{Level, LevelFilter}; use serde::{Deserialize, Serialize}; use uuid::Uuid; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Config { pub bot: BotConfig, pub permissions: PermissionsGroups, pub relay: RelayConfig, pub logging: LoggingConfig, pub locations: HashMap } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct BotConfig { pub discord_token: String, pub prefix: String } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RelayConfig { pub ip: Ipv4Addr, pub port: u16, pub channels: Vec, pub webhooks: Vec, pub protocol_version: u64, pub username: String, pub uuid: Uuid, pub microsoft_email: String, pub owner_username: String, pub owner_uuid_undashed: String, pub ignored: Vec } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct PermissionsGroups { pub owner: PermissionGroup, pub admin: PermissionGroup } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct PermissionGroup { pub user_members: Vec, pub group_members: Vec, pub uuid_members: Vec } #[derive(Serialize, Deserialize, Debug, Clone)] pub struct LoggingConfig { pub enabled: bool, pub level: LogLevel } #[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "snake_case")] pub enum LogLevel { Debug, Error, Info, Trace, Warn } impl From for Level { fn from(value: LogLevel) -> Self { match value { LogLevel::Debug => Level::Debug, LogLevel::Error => Level::Error, LogLevel::Info => Level::Info, LogLevel::Trace => Level::Trace, LogLevel::Warn => Level::Warn } } } pub fn load_config() -> Config { let mut args = env::args(); if args.len() != 2 { eprintln!("usage: discord_bot "); std::process::exit(1); } let config_path = args.nth(1).unwrap(); if !Path::new(&config_path).exists() { eprintln!("err: config file does not exist"); eprintln!("usage: discord_bot "); std::process::exit(1); } let config_str = match fs::read_to_string(config_path) { Ok(r) => r, Err(e) => { eprintln!("error loading config: {}", e); std::process::exit(1); } }; let config: Config = match toml::from_str(&config_str) { Ok(r) => r, Err(e) => { eprintln!("error parsing config: {}", e); std::process::exit(1); } }; config } pub fn save_config(config: &Config) { let mut args = env::args(); if args.len() != 2 { eprintln!("usage: discord_bot "); std::process::exit(1); } let config_path = args.nth(1).unwrap(); if !Path::new(&config_path).exists() { eprintln!("err: config file does not exist"); eprintln!("usage: discord_bot "); std::process::exit(1); } let config = match toml::to_string(&config) { Ok(r) => r, Err(e) => { eprintln!("error saving config: {}", e); std::process::exit(1); } }; match fs::write(config_path, config) { Ok(r) => r, Err(e) => { eprintln!("error saving config: {}", e); std::process::exit(1); } }; }