use std::sync::Arc;
use super::{ErrorRenderer, HandlerError};
use crate::types::{
ApplicationCommandInteractionData, DataInteraction, Entitlement, Member, MessageComponentData,
ModalSubmitData, Snowflake, User,
};
pub struct Ctx<'a, S = (), D = ApplicationCommandInteractionData> {
interaction: &'a Arc<DataInteraction<D>>,
state: &'a S,
errors: ErrorRenderer,
}
pub type ComponentCtx<'a, S = ()> = Ctx<'a, S, MessageComponentData>;
pub type ModalCtx<'a, S = ()> = Ctx<'a, S, ModalSubmitData>;
impl<S, D> Clone for Ctx<'_, S, D> {
fn clone(&self) -> Self {
*self
}
}
impl<S, D> Copy for Ctx<'_, S, D> {}
impl<'a, S, D> Ctx<'a, S, D> {
pub fn new(interaction: &'a Arc<DataInteraction<D>>, state: &'a S) -> Self {
Self {
interaction,
state,
errors: HandlerError::response,
}
}
pub fn with_errors(mut self, errors: ErrorRenderer) -> Self {
self.errors = errors;
self
}
#[cfg(feature = "rest")]
pub(crate) fn errors(&self) -> ErrorRenderer {
self.errors
}
pub fn interaction(&self) -> &'a DataInteraction<D> {
self.interaction
}
#[cfg(feature = "rest")]
pub(crate) fn shared_interaction(&self) -> &'a Arc<DataInteraction<D>> {
self.interaction
}
pub fn data(&self) -> &'a D {
&self.interaction.data
}
pub fn state(&self) -> &'a S {
self.state
}
pub fn user(&self) -> Option<&'a User> {
self.interaction.common.invoking_user()
}
pub fn member(&self) -> Option<&'a Member> {
self.interaction.common.member.as_ref()
}
pub fn guild_id(&self) -> Option<&'a Snowflake> {
self.interaction.common.guild_id.as_ref()
}
pub fn channel_id(&self) -> Option<&'a Snowflake> {
self.interaction.common.channel_id.as_ref()
}
pub fn locale(&self) -> Option<&'a str> {
self.interaction.locale.as_deref()
}
pub fn entitlements(&self) -> &'a [Entitlement] {
&self.interaction.common.entitlements
}
pub fn is_entitled(&self, sku_id: Snowflake) -> bool {
self.entitlements()
.iter()
.any(|e| e.sku_id == sku_id && !e.deleted && e.consumed != Some(true))
}
}
impl<'a, S> ComponentCtx<'a, S> {
pub fn values(&self) -> &'a [String] {
self.interaction.data.values.as_deref().unwrap_or_default()
}
}
impl<'a, S> ModalCtx<'a, S> {
pub fn value(&self, custom_id: &str) -> Option<&'a str> {
self.interaction.data.value(custom_id)
}
pub fn values(&self, custom_id: &str) -> &'a [String] {
self.interaction.data.values(custom_id).unwrap_or_default()
}
pub fn checked(&self, custom_id: &str) -> Option<bool> {
self.interaction.data.checked(custom_id)
}
}