feat: command handling, make initializing VCs concurrent

This commit is contained in:
2026-03-25 16:55:54 -04:00
parent 67bdc9e451
commit d9e0801ec9
7 changed files with 183 additions and 66 deletions

View File

@@ -1,12 +1,16 @@
use clap::Parser;
use fomo_reducer::{VCs, all_commands, initialize_vcs, update_vcs};
use fomo_reducer::{CommandRouter, State, VCs, all_commands, initialize_vcs, update_vcs};
use opendal::{IntoOperatorUri, Operator, OperatorUri};
use secrecy::{ExposeSecret, SecretString};
use snafu::Snafu;
use std::{fmt::Debug, str::FromStr};
use std::{fmt::Debug, str::FromStr, sync::Arc};
use tracing_subscriber::{EnvFilter, fmt::format::FmtSpan};
use twilight_gateway::{Event, EventTypeFlags, Intents, Shard, ShardId, StreamExt};
use twilight_model::id::{Id, marker::UserMarker};
use twilight_model::{
application::interaction::InteractionData,
gateway::payload::incoming::InteractionCreate,
id::{Id, marker::UserMarker},
};
#[derive(Clone)]
struct OpendalOperator {
@@ -126,7 +130,7 @@ async fn main() -> Result<(), MainError> {
let commands = all_commands();
let returned_commands = interaction_client
let _returned_commands = interaction_client
.set_global_commands(
Vec::from_iter(
commands
@@ -141,13 +145,16 @@ async fn main() -> Result<(), MainError> {
.await
.expect("failed to deserialize set commands"); // TODO
let mut voice_status = initialize_vcs(&discord_client).await;
let command_router = CommandRouter::from_iter(commands);
let vcs = initialize_vcs(&discord_client).await;
let vcs = Arc::new(vcs);
while let Some(event_res) = next_event.await {
match event_res {
Ok(event) => {
tracing::debug!(?voice_status, "before handling");
handle_event(event, &mut voice_status).await;
tracing::debug!(?voice_status, "after handling");
tracing::debug!(?vcs, "before handling");
handle_event(&command_router, vcs.clone(), event).await;
tracing::debug!(?vcs, "after handling");
}
Err(error) => {
tracing::error!(?error);
@@ -160,14 +167,45 @@ async fn main() -> Result<(), MainError> {
Ok(())
}
#[tracing::instrument(skip(vcs))]
async fn handle_event(event: Event, vcs: &mut VCs) {
#[tracing::instrument(skip(command_router, vcs))]
async fn handle_event(command_router: &CommandRouter, vcs: Arc<VCs>, event: Event) {
match event {
Event::VoiceStateUpdate(voice_state_update) => {
update_vcs(&voice_state_update, vcs);
update_vcs(&voice_state_update, &vcs);
}
other => {
tracing::warn!(?other, "wasn't expected");
Event::InteractionCreate(interaction_create) => {
let InteractionCreate(interaction) = *interaction_create;
match interaction.data {
None => {
tracing::warn!("missing expected interaction data");
}
Some(InteractionData::ApplicationCommand(command_data)) => {
let state = State { vcs };
command_router.handle(state, *command_data).await;
}
Some(InteractionData::MessageComponent(component_data)) => {
tracing::warn!(
?component_data,
"wasn't expected because this bot has no modal features"
);
}
Some(InteractionData::ModalSubmit(modal_data)) => {
tracing::warn!(
?modal_data,
"wasn't expected because this bot has no modal features"
);
}
Some(other_interaction_data) => {
tracing::warn!(?other_interaction_data, "wasn't expected");
}
}
}
other_event => {
tracing::warn!(?other_event, "wasn't expected");
}
}
}