Reorganize command wrappers

This commit is contained in:
Joscha 2024-12-27 17:56:54 +01:00
parent 7928eda0d0
commit 12448c26c9
5 changed files with 116 additions and 102 deletions

View file

@ -1,8 +1,7 @@
pub mod bang;
pub mod basic;
#[cfg(feature = "clap")]
pub mod clap;
mod hidden;
mod prefixed;
use std::future::Future;
@ -15,8 +14,6 @@ use euphoxide::{
},
};
pub use self::{hidden::*, prefixed::*};
#[non_exhaustive]
pub struct Context {
pub conn: ClientConnHandle,

View file

@ -1,3 +1,5 @@
//! Euphoria-style `!foo` and `!foo @bar` command wrappers.
use async_trait::async_trait;
use euphoxide::{api::Message, nick};

View file

@ -0,0 +1,113 @@
//! Basic command wrappers.
use async_trait::async_trait;
use euphoxide::api::Message;
use super::{Command, Context, Info, Propagate};
/// Rewrite or hide command info.
pub struct Described<C> {
pub inner: C,
pub trigger: Option<Option<String>>,
pub description: Option<Option<String>>,
}
impl<C> Described<C> {
pub fn new(inner: C) -> Self {
Self {
inner,
trigger: None,
description: None,
}
}
pub fn hidden(inner: C) -> Self {
Self::new(inner)
.with_trigger_hidden()
.with_description_hidden()
}
pub fn with_trigger(mut self, trigger: impl ToString) -> Self {
self.trigger = Some(Some(trigger.to_string()));
self
}
pub fn with_trigger_hidden(mut self) -> Self {
self.trigger = Some(None);
self
}
pub fn with_description(mut self, description: impl ToString) -> Self {
self.description = Some(Some(description.to_string()));
self
}
pub fn with_description_hidden(mut self) -> Self {
self.description = Some(None);
self
}
}
#[async_trait]
impl<B, E, C> Command<B, E> for Described<C>
where
B: Send,
C: Command<B, E> + Send + Sync,
{
fn info(&self, ctx: &Context) -> Info {
let info = self.inner.info(ctx);
Info {
trigger: self.trigger.clone().unwrap_or(info.trigger),
description: self.description.clone().unwrap_or(info.description),
}
}
async fn execute(
&self,
arg: &str,
msg: &Message,
ctx: &Context,
bot: &mut B,
) -> Result<Propagate, E> {
self.inner.execute(arg, msg, ctx, bot).await
}
}
pub struct Prefixed<C> {
prefix: String,
inner: C,
}
impl<C> Prefixed<C> {
pub fn new<S: ToString>(prefix: S, inner: C) -> Self {
Self {
prefix: prefix.to_string(),
inner,
}
}
}
#[async_trait]
impl<B, E, C> Command<B, E> for Prefixed<C>
where
B: Send,
C: Command<B, E> + Send + Sync,
{
fn info(&self, ctx: &Context) -> Info {
self.inner.info(ctx).with_prepended_trigger(&self.prefix)
}
async fn execute(
&self,
arg: &str,
msg: &Message,
ctx: &Context,
bot: &mut B,
) -> Result<Propagate, E> {
if let Some(rest) = arg.trim_start().strip_prefix(&self.prefix) {
self.inner.execute(rest, msg, ctx, bot).await
} else {
Ok(Propagate::Yes)
}
}
}

View file

@ -1,55 +0,0 @@
use async_trait::async_trait;
use euphoxide::api::Message;
use super::{Command, Context, Info, Propagate};
pub struct Hidden<C> {
pub inner: C,
pub allow_trigger: bool,
pub allow_description: bool,
}
impl<C> Hidden<C> {
pub fn new(inner: C) -> Self {
Self {
inner,
allow_trigger: false,
allow_description: false,
}
}
pub fn with_allow_trigger(mut self, allow: bool) -> Self {
self.allow_trigger = allow;
self
}
pub fn with_allow_description(mut self, allow: bool) -> Self {
self.allow_description = allow;
self
}
}
#[async_trait]
impl<B, E, C> Command<B, E> for Hidden<C>
where
B: Send,
C: Command<B, E> + Send + Sync,
{
fn info(&self, ctx: &Context) -> Info {
let info = self.inner.info(ctx);
Info {
trigger: info.trigger.filter(|_| self.allow_trigger),
description: info.description.filter(|_| self.allow_description),
}
}
async fn execute(
&self,
arg: &str,
msg: &Message,
ctx: &Context,
bot: &mut B,
) -> Result<Propagate, E> {
self.inner.execute(arg, msg, ctx, bot).await
}
}

View file

@ -1,43 +0,0 @@
use async_trait::async_trait;
use euphoxide::api::Message;
use super::{Command, Context, Info, Propagate};
pub struct Prefixed<C> {
prefix: String,
inner: C,
}
impl<C> Prefixed<C> {
pub fn new<S: ToString>(prefix: S, inner: C) -> Self {
Self {
prefix: prefix.to_string(),
inner,
}
}
}
#[async_trait]
impl<B, E, C> Command<B, E> for Prefixed<C>
where
B: Send,
C: Command<B, E> + Send + Sync,
{
fn info(&self, ctx: &Context) -> Info {
self.inner.info(ctx).with_prepended_trigger(&self.prefix)
}
async fn execute(
&self,
arg: &str,
msg: &Message,
ctx: &Context,
bot: &mut B,
) -> Result<Propagate, E> {
if let Some(rest) = arg.trim_start().strip_prefix(&self.prefix) {
self.inner.execute(rest, msg, ctx, bot).await
} else {
Ok(Propagate::Yes)
}
}
}