1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
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, sync::Arc};
#[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.
lambo::configure_logger(args.quiet, args.verbose)?;
// 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 {
config: Arc::new(config.x500_mapper),
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(())
}
|