serenity/framework/standard/structures/
check.rs

1use std::error::Error;
2use std::fmt;
3
4use futures::future::BoxFuture;
5
6use crate::client::Context;
7use crate::framework::standard::{Args, CommandOptions};
8use crate::model::channel::Message;
9
10/// This type describes why a check has failed.
11///
12/// **Note**: The bot-developer is supposed to process this `enum` as the framework is not. It
13/// solely serves as a way to inform a user about why a check has failed and for the developer to
14/// log given failure (e.g. bugs or statistics) occurring in [`Check`]s.
15#[derive(Clone, Debug)]
16#[non_exhaustive]
17pub enum Reason {
18    /// No information on the failure.
19    Unknown,
20    /// Information dedicated to the user.
21    User(String),
22    /// Information purely for logging purposes.
23    Log(String),
24    /// Information for the user but also for logging purposes.
25    UserAndLog { user: String, log: String },
26}
27
28impl Error for Reason {}
29
30pub type CheckFunction = for<'fut> fn(
31    &'fut Context,
32    &'fut Message,
33    &'fut mut Args,
34    &'fut CommandOptions,
35) -> BoxFuture<'fut, Result<(), Reason>>;
36
37/// A check can be part of a command or group and will be executed to determine whether a user is
38/// permitted to use related item.
39///
40/// Additionally, a check may hold additional settings.
41pub struct Check {
42    /// Name listed in help-system.
43    pub name: &'static str,
44    /// Function that will be executed.
45    pub function: CheckFunction,
46    /// Whether a check should be evaluated in the help-system. `false` will ignore check and won't
47    /// fail execution.
48    pub check_in_help: bool,
49    /// Whether a check shall be listed in the help-system. `false` won't affect whether the check
50    /// will be evaluated help, solely [`Self::check_in_help`] sets this.
51    pub display_in_help: bool,
52}
53
54impl fmt::Debug for Check {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        f.debug_struct("Check")
57            .field("name", &self.name)
58            .field("function", &"<fn>")
59            .field("check_in_help", &self.check_in_help)
60            .field("display_in_help", &self.display_in_help)
61            .finish()
62    }
63}
64
65impl fmt::Display for Reason {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        match self {
68            Self::Unknown => f.write_str("Unknown"),
69            Self::User(reason) => write!(f, "User {reason}"),
70            Self::Log(reason) => write!(f, "Log {reason}"),
71            Self::UserAndLog {
72                user,
73                log,
74            } => {
75                write!(f, "UserAndLog {{user: {user}, log: {log}}}")
76            },
77        }
78    }
79}
80
81impl PartialEq for Check {
82    fn eq(&self, other: &Self) -> bool {
83        self.name == other.name
84    }
85}