Files
robotnik/src/setup.rs

125 lines
4.0 KiB
Rust
Raw Normal View History

2025-11-22 06:20:56 -06:00
//! Handles configuration for the bot.
//!
//! Both command line, and configuration file options are handled here.
2025-08-05 01:47:11 -05:00
use clap::Parser;
2025-11-09 00:02:38 -06:00
use color_eyre::{Result, eyre::WrapErr};
2025-08-05 01:47:11 -05:00
use config::Config;
use directories::ProjectDirs;
use std::path::PathBuf;
2025-11-09 00:02:38 -06:00
use tracing::{info, instrument};
2025-08-05 01:47:11 -05:00
// TODO: use [clap(long, short, help_heading = Some(section))]
2025-11-22 06:20:56 -06:00
/// Struct of potential arguments.
2025-08-05 01:47:11 -05:00
#[derive(Clone, Debug, Parser)]
#[command(about, version)]
pub struct Args {
2025-08-05 01:47:11 -05:00
#[arg(short, long)]
/// API Key for the LLM in use.
pub api_key: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(short, long, default_value = "https://api.openai.com")]
/// Base URL for the LLM API to use.
pub base_url: Option<String>,
2025-08-05 01:47:11 -05:00
2025-08-11 19:31:38 -05:00
/// Directory to use for chroot (recommended).
#[arg(long)]
pub chroot_dir: Option<String>,
2025-08-11 19:31:38 -05:00
/// Root directory for file based command structure.
#[arg(long)]
pub command_dir: Option<String>,
2025-08-11 19:31:38 -05:00
2025-08-05 01:47:11 -05:00
#[arg(long)]
/// Instructions to the model on how to behave.
pub instruct: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(long)]
2025-11-22 06:20:56 -06:00
/// Name of the model to use. E.g. 'deepseek-chat'
pub model: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(long)]
/// List of IRC channels to join.
pub channels: Option<Vec<String>>,
2025-08-05 01:47:11 -05:00
#[arg(short, long)]
/// Custom configuration file location if need be.
pub config_file: Option<PathBuf>,
2025-08-05 01:47:11 -05:00
#[arg(short, long, default_value = "irc.libera.chat")]
/// IRC server.
pub server: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(short, long, default_value = "6697")]
/// Port of the IRC server.
pub port: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(long)]
/// IRC Nickname.
pub nickname: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(long)]
/// IRC Nick Password
pub nick_password: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(long)]
/// IRC Username
pub username: Option<String>,
2025-08-05 01:47:11 -05:00
#[arg(long)]
/// Whether or not to use TLS when connecting to the IRC server.
pub use_tls: Option<bool>,
2025-08-05 01:47:11 -05:00
}
2025-11-22 06:20:56 -06:00
/// Handle for interacting with the bot configuration.
pub struct Setup {
2025-11-22 06:20:56 -06:00
/// Handle for the configuration file options.
pub config: Config,
2025-08-05 01:47:11 -05:00
}
#[instrument]
2025-11-22 06:20:56 -06:00
/// Initialize a new [`Setup`] instance.
///
/// This reads the settings file which becomes the bot's default configuration.
/// These settings shall be overridden by any command line options.
2025-08-05 01:47:11 -05:00
pub async fn init() -> Result<Setup> {
// Get arguments. These overrule configuration file, and environment
// variables if applicable.
let args = Args::parse();
// Use default config location unless specified.
let config_location: PathBuf = if let Some(ref path) = args.config_file {
path.to_owned()
} else {
ProjectDirs::from("", "", env!("CARGO_PKG_NAME"))
.unwrap()
.config_dir()
.to_owned()
.join(r"config.toml")
};
info!("Starting.");
let settings = Config::builder()
.add_source(config::File::with_name(&config_location.to_string_lossy()).required(false))
.add_source(config::Environment::with_prefix("BOT"))
// Doing all of these overrides provides a unified access point for options,
// but a derive macro could do this a bit better if this becomes too large.
.set_override_option("api-key", args.api_key.clone())?
.set_override_option("base-url", args.base_url.clone())?
2025-08-11 19:31:38 -05:00
.set_override_option("chroot-dir", args.chroot_dir.clone())?
.set_override_option("command-path", args.command_dir.clone())?
2025-08-05 01:47:11 -05:00
.set_override_option("model", args.model.clone())?
2025-11-03 22:31:13 -06:00
.set_override_option("instruct", args.instruct.clone())?
2025-08-05 01:47:11 -05:00
.set_override_option("channels", args.channels.clone())?
.set_override_option("server", args.server.clone())?
.set_override_option("port", args.port.clone())? // FIXME: Make this a default here not in clap.
.set_override_option("nickname", args.nickname.clone())?
.set_override_option("username", args.username.clone())?
.set_override_option("use_tls", args.use_tls)?
.build()
.wrap_err("Couldn't read configuration settings.")?;
Ok(Setup { config: settings })
}