1use anyhow::Context;
7use serenity::all::GuildId;
8
9#[derive(Debug, Clone)]
11pub struct Config {
12 pub discord_token: String,
14 pub guild_id: Option<u64>,
16 pub log_level: String,
18 pub default_votekick_duration: u64,
20 pub min_votekick_duration: u64,
22 pub max_votekick_duration: u64,
24}
25
26impl Config {
27 pub fn from_env() -> anyhow::Result<Self> {
29 let discord_token = std::env::var("DISCORD_TOKEN")
30 .context("DISCORD_TOKEN environment variable is required")?;
31
32 let guild_id = std::env::var("GUILD_ID").ok().and_then(|v| v.parse().ok());
33
34 let log_level = std::env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
35
36 let default_votekick_duration = std::env::var("DEFAULT_VOTEKICK_DURATION")
37 .ok()
38 .and_then(|v| v.parse().ok())
39 .unwrap_or(60);
40
41 let min_votekick_duration = std::env::var("MIN_VOTEKICK_DURATION")
42 .ok()
43 .and_then(|v| v.parse().ok())
44 .unwrap_or(10);
45
46 let max_votekick_duration = std::env::var("MAX_VOTEKICK_DURATION")
47 .ok()
48 .and_then(|v| v.parse().ok())
49 .unwrap_or(300);
50
51 Ok(Self {
52 discord_token,
53 guild_id,
54 log_level,
55 default_votekick_duration,
56 min_votekick_duration,
57 max_votekick_duration,
58 })
59 }
60
61 pub fn guild_id(&self) -> Option<GuildId> {
63 self.guild_id.map(GuildId::new)
64 }
65}
66
67pub fn init() -> anyhow::Result<Config> {
69 let config = Config::from_env()?;
70 let subscriber = tracing_subscriber::fmt()
71 .with_env_filter(
72 tracing_subscriber::EnvFilter::try_from_default_env()
73 .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(&config.log_level)),
74 )
75 .finish();
76
77 tracing::subscriber::set_global_default(subscriber)
78 .context("Failed to set global default subscriber")?;
79
80 Ok(config)
81}