aboutsummaryrefslogtreecommitdiff
path: root/src/bin/lambo.rs
diff options
context:
space:
mode:
authorNathan Ringo <nathan@remexre.com>2024-01-16 00:57:41 -0600
committerNathan Ringo <nathan@remexre.com>2024-01-16 00:57:41 -0600
commited778ab2060c6131caf98231a97873d7ea490d5a (patch)
treebfa6ceca8fe2e209562c1e995c598d80be0e4501 /src/bin/lambo.rs
parent54f497163f57dacd8d621a2a3c89e1f06ac370d0 (diff)
The start of database functionality.
Diffstat (limited to 'src/bin/lambo.rs')
-rw-r--r--src/bin/lambo.rs85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/bin/lambo.rs b/src/bin/lambo.rs
new file mode 100644
index 0000000..e3e81a6
--- /dev/null
+++ b/src/bin/lambo.rs
@@ -0,0 +1,85 @@
+use anyhow::{Context as _, Result};
+use clap::{value_parser, ArgAction, Parser};
+use lambo::{config::Config, handlers::*};
+use serenity::{all::GatewayIntents, Client};
+use sqlx::sqlite::SqlitePoolOptions;
+use std::path::PathBuf;
+use stderrlog::StdErrLog;
+
+#[derive(Debug, Parser)]
+struct Args {
+ /// The path to the lambo configuration file.
+ config_path: PathBuf,
+
+ /// Decreases the log level.
+ #[clap(
+ short,
+ long,
+ conflicts_with("verbose"),
+ action = ArgAction::Count,
+ value_parser = value_parser!(u8).range(..=2)
+ )]
+ quiet: u8,
+
+ /// Increases the log level.
+ #[clap(
+ short,
+ long,
+ conflicts_with("quiet"),
+ action = ArgAction::Count,
+ value_parser = value_parser!(u8).range(..=3)
+ )]
+ verbose: u8,
+}
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ // Parse the arguments.
+ let args = Args::parse();
+
+ // Set up logging.
+ {
+ let mut logger = StdErrLog::new();
+ match args.quiet {
+ 0 => logger.verbosity(1 + args.verbose as usize),
+ 1 => logger.verbosity(0),
+ 2 => logger.quiet(true),
+ // UNREACHABLE: A maximum of two occurrences of quiet are allowed.
+ _ => unreachable!(),
+ };
+ // UNWRAP: No other logger should be set up.
+ logger.show_module_names(true).init().unwrap()
+ }
+
+ // Parse the config file.
+ let config = Config::read_from_file(&args.config_path)?;
+
+ // Connect to the database.
+ let db = SqlitePoolOptions::new()
+ .connect(&config.database_url)
+ .await
+ .with_context(|| format!("failed to connect to database at {:?}", config.database_url))?;
+
+ // Run any necessary migrations.
+ sqlx::migrate!().run(&db).await.with_context(|| {
+ format!(
+ "failed to run migrations on database at {:?}",
+ config.database_url
+ )
+ })?;
+
+ // Create the handlers.
+ let handler = MultiHandler(vec![Box::new(PresenceSetter), Box::new(X500Mapper(db))]);
+
+ // Start up the client.
+ let intents = GatewayIntents::default() | GatewayIntents::GUILD_MEMBERS;
+ Client::builder(&config.discord_token, intents)
+ .event_handler(handler)
+ .await
+ .context("failed to create Discord client")?
+ .start()
+ .await
+ .context("failed to start Discord client")?;
+
+ Ok(())
+}