use std::error::Error;
use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use twilight_model::gateway::payload::incoming::MessageCreate;
use crate::state::StateBound;
use crate::utils::pinbox;
#[derive(Clone)]
pub struct PrefixesContext<State = ()>
where
State: StateBound,
{
pub state: State,
pub event: MessageCreate,
}
pub type PrefixesResult = Result<Vec<String>, Arc<dyn Error + Send + Sync>>;
pub trait IntoPrefixesResult {
fn into_prefixes_result(self) -> PrefixesResult;
}
impl IntoPrefixesResult for Vec<String> {
fn into_prefixes_result(self) -> PrefixesResult {
Ok(self)
}
}
impl<T, E> IntoPrefixesResult for Result<T, E>
where
T: Into<Vec<String>>,
E: Error + Send + Sync + 'static,
{
fn into_prefixes_result(self) -> PrefixesResult {
match self {
Ok(v) => Ok(v.into()),
Err(e) => Err(Arc::new(e)),
}
}
}
pub trait Prefixes<State = ()>: Send + Sync
where
State: StateBound,
{
fn get(
&self,
context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>>;
}
impl<State> Prefixes<State> for &str
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(vec![self.to_string()]))
}
}
impl<State> Prefixes<State> for String
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(vec![self.clone()]))
}
}
impl<State> Prefixes<State> for Vec<&str>
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(self.iter().map(|s| s.to_string()).collect()))
}
}
impl<State> Prefixes<State> for Vec<String>
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(self.clone()))
}
}
impl<State> Prefixes<State> for &[String]
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(self.to_vec()))
}
}
impl<State> Prefixes<State> for &[&str]
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(self.iter().map(|s| s.to_string()).collect()))
}
}
impl<State, const N: usize> Prefixes<State> for [&str; N]
where
State: StateBound,
{
fn get(
&self,
_context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
pinbox(Ok(self.iter().map(|s| s.to_string()).collect()))
}
}
impl<State, Func, Fut, Res> Prefixes<State> for Func
where
State: StateBound,
Func: Fn(PrefixesContext<State>) -> Fut + Send + Sync + 'static,
Fut: Future<Output = Res> + Send + 'static,
Res: IntoPrefixesResult,
{
fn get(
&self,
context: PrefixesContext<State>,
) -> Pin<Box<dyn Future<Output = PrefixesResult> + Send + '_>> {
Box::pin(async move { (self)(context).await.into_prefixes_result() })
}
}